Michael DOUBEZ writes:"condo4" writes:Bonjour,
Je souhaite créer une classe pour créer des log.
Class SysLog
j'aimerai utiliser comme ceci :
SysLog a;
a<<"Chaine a logguer : "<<45;
La technique habituelle consiste a creer ton propre streambuf. Un exemple
dans la FAQ. On doit pouvoir en trouver d'autres en faisant une recherche
dans les archives.
En général mais si il crée son streambuf il va avoir un log du type
2007-03-06 13:20:42 - Chaine a logguer :
2007-03-06 13:20:42 - 45
Il faut naturellement choisir ou on veut la chaine d'identification.
Quelques solutions:
- a chaque ligne
- a chaque flush
- avec un formatteur special.
Michael DOUBEZ <michael.doubez@free.fr> writes:
"condo4" <c4@saint-pal.com> writes:
Bonjour,
Je souhaite créer une classe pour créer des log.
Class SysLog
j'aimerai utiliser comme ceci :
SysLog a;
a<<"Chaine a logguer : "<<45;
La technique habituelle consiste a creer ton propre streambuf. Un exemple
dans la FAQ. On doit pouvoir en trouver d'autres en faisant une recherche
dans les archives.
En général mais si il crée son streambuf il va avoir un log du type
2007-03-06 13:20:42 - Chaine a logguer :
2007-03-06 13:20:42 - 45
Il faut naturellement choisir ou on veut la chaine d'identification.
Quelques solutions:
- a chaque ligne
- a chaque flush
- avec un formatteur special.
Michael DOUBEZ writes:"condo4" writes:Bonjour,
Je souhaite créer une classe pour créer des log.
Class SysLog
j'aimerai utiliser comme ceci :
SysLog a;
a<<"Chaine a logguer : "<<45;
La technique habituelle consiste a creer ton propre streambuf. Un exemple
dans la FAQ. On doit pouvoir en trouver d'autres en faisant une recherche
dans les archives.
En général mais si il crée son streambuf il va avoir un log du type
2007-03-06 13:20:42 - Chaine a logguer :
2007-03-06 13:20:42 - 45
Il faut naturellement choisir ou on veut la chaine d'identification.
Quelques solutions:
- a chaque ligne
- a chaque flush
- avec un formatteur special.
En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
[...]
Encore, en général : il s'agit ici d'un type à sémantique de
valeur. Et les valeurs, en général, je ne les manipule pas à
travers les pointeurs.
En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
[...]
Encore, en général : il s'agit ici d'un type à sémantique de
valeur. Et les valeurs, en général, je ne les manipule pas à
travers les pointeurs.
En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
[...]
Encore, en général : il s'agit ici d'un type à sémantique de
valeur. Et les valeurs, en général, je ne les manipule pas à
travers les pointeurs.
James Kanze wrote on 07/03/2007 10:05:En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
"programmation défensive" comme tu dis, ça parait sain, en effet.pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) sera it
l'injection désordonnée des informations.
sur ce point la simple écriture:
log << "bla" << i << endl;
n'est pas protégée.
l'écriture:
log.startRecord();
log << "bla" << i << endl;
log.endRecord();
protège le contenu du log mais au prix d'un assert.
est-ce qu'un string (mutable) "time-stampé" (constructeur s'injectant le
date/time courant et/ou méthode de 'reset') utilisé avec un ofstream
classique ne ferait pas l'affaire ?
timestring ts;
ts.clear();
log << (ts << "bla" << i << endl);
ts.clear();
log << (ts << "foo" << j << endl);
James Kanze wrote on 07/03/2007 10:05:
En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
"programmation défensive" comme tu dis, ça parait sain, en effet.
pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) sera it
l'injection désordonnée des informations.
sur ce point la simple écriture:
log << "bla" << i << endl;
n'est pas protégée.
l'écriture:
log.startRecord();
log << "bla" << i << endl;
log.endRecord();
protège le contenu du log mais au prix d'un assert.
est-ce qu'un string (mutable) "time-stampé" (constructeur s'injectant le
date/time courant et/ou méthode de 'reset') utilisé avec un ofstream
classique ne ferait pas l'affaire ?
timestring ts;
ts.clear();
log << (ts << "bla" << i << endl);
ts.clear();
log << (ts << "foo" << j << endl);
James Kanze wrote on 07/03/2007 10:05:En général, j'évite des conversions implicites chaque fois que
je peux. Et en général, j'estîme que l'utilisation d'explicit
dans le cas des constructeurs à un seul paramètre doit être un
automatisme, dont on s'écarte uniquement quand on veut
explicitement une conversion implicite (ce qui doit être assez
rare).
"programmation défensive" comme tu dis, ça parait sain, en effet.pourquoi recopier la struct tm sur la pile ?
Habitude. Dans la pratique, j'utilise prèsque toujours la
fonction non standard localtime_r, qui exige l'adresse du buffer
sur la pile (et qui marche aussi dans une contexte
multithreaded).
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) sera it
l'injection désordonnée des informations.
sur ce point la simple écriture:
log << "bla" << i << endl;
n'est pas protégée.
l'écriture:
log.startRecord();
log << "bla" << i << endl;
log.endRecord();
protège le contenu du log mais au prix d'un assert.
est-ce qu'un string (mutable) "time-stampé" (constructeur s'injectant le
date/time courant et/ou méthode de 'reset') utilisé avec un ofstream
classique ne ferait pas l'affaire ?
timestring ts;
ts.clear();
log << (ts << "bla" << i << endl);
ts.clear();
log << (ts << "foo" << j << endl);
et est-ce qu'il ne serait pas possible d'heriter de ofstream ?
Du style :
using namespace std;
class LogSys: public ofstream{
public:
__ostream_type & operator<< (__streambuf_type *__sb);
};
__ostream_type & LogSys::operator<< (__streambuf_type *__sb){
char now[31];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime (&rawtime);
strftime(now,100,"%Y/%m/%d %H:%M:%S : ",timeinfo);
//Et la on appel la fonction de l'ancetre avec now devant __sb ????
}
et est-ce qu'il ne serait pas possible d'heriter de ofstream ?
Du style :
using namespace std;
class LogSys: public ofstream{
public:
__ostream_type & operator<< (__streambuf_type *__sb);
};
__ostream_type & LogSys::operator<< (__streambuf_type *__sb){
char now[31];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime (&rawtime);
strftime(now,100,"%Y/%m/%d %H:%M:%S : ",timeinfo);
//Et la on appel la fonction de l'ancetre avec now devant __sb ????
}
et est-ce qu'il ne serait pas possible d'heriter de ofstream ?
Du style :
using namespace std;
class LogSys: public ofstream{
public:
__ostream_type & operator<< (__streambuf_type *__sb);
};
__ostream_type & LogSys::operator<< (__streambuf_type *__sb){
char now[31];
time_t rawtime;
struct tm * timeinfo;
time(&rawtime);
timeinfo = localtime (&rawtime);
strftime(now,100,"%Y/%m/%d %H:%M:%S : ",timeinfo);
//Et la on appel la fonction de l'ancetre avec now devant __sb ????
}
[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) serait
l'injection désordonnée des informations.
[...]
[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) serait
l'injection désordonnée des informations.
[...]
[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait pas
si grave) toutefois le problème plus génant (en multi threading) serait
l'injection désordonnée des informations.
[...]
Sylvain wrote:[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait p as
si grave) toutefois le problème plus génant (en multi threading) se rait
l'injection désordonnée des informations.
[...]
Malheureusement je ne peux pas être précis, car ce n'était pas mon
programme, et je ne me souviens plus des détails, mais un collègue a une
fois identifié la source d'un problème de crash sur Solaris comme ven ant
juste de l'appel d'une fonction de temps non thread-safe.
Et pourtant on avait du mal à comprendre comment ça pouvait avoir pour
conséquence un crash ...
Sylvain wrote:
[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait p as
si grave) toutefois le problème plus génant (en multi threading) se rait
l'injection désordonnée des informations.
[...]
Malheureusement je ne peux pas être précis, car ce n'était pas mon
programme, et je ne me souviens plus des détails, mais un collègue a une
fois identifié la source d'un problème de crash sur Solaris comme ven ant
juste de l'appel d'une fonction de temps non thread-safe.
Et pourtant on avait du mal à comprendre comment ça pouvait avoir pour
conséquence un crash ...
Sylvain wrote:[...]
merci, ainsi qu'à Jean-Marc, pour ces explications, je suis d'accord
avec vous sur cette protection safe-thread (qui coute suffisamment peu
pour la retenir, même si une date fausse de qlq ms ne me paraissait p as
si grave) toutefois le problème plus génant (en multi threading) se rait
l'injection désordonnée des informations.
[...]
Malheureusement je ne peux pas être précis, car ce n'était pas mon
programme, et je ne me souviens plus des détails, mais un collègue a une
fois identifié la source d'un problème de crash sur Solaris comme ven ant
juste de l'appel d'une fonction de temps non thread-safe.
Et pourtant on avait du mal à comprendre comment ça pouvait avoir pour
conséquence un crash ...