OVH Cloud OVH Cloud

Définir une classe log et l'utiliser comme cerr

32 réponses
Avatar
Cornu Nicolas
Bonjour,

J'aimerais définir une classe log
et l'utiliser comme cerr.

log << "erreur";

J'ai éssayer plusieurs surcharge de l'opérateur <<
en définissant à l'extèrieur de la classe log une surcharge
sans succès


Merci d'avance,

Cornu Nicolas

2 réponses

1 2 3 4
Avatar
Aurélien REGAT-BARREL
wrote:
log( log_warning ) << "warning" ;

Du coup, la fonction log() renvoie une référence au flux, et le
tour est joué.


C'est ce que j'utilise personnelement, mais via des macros.

/// log_trace() : Logger des messages de traçage
#define log_trace()
Logger::get_log( "TRACE", __LINE__, __FUNCTION__ )

/// log_error() : Logger des messages d'erreur
#define log_error()
Logger::get_log( "ERROR", __LINE__, __FUNCTION__ )

/// log_catch() : Logger les exceptions catchées
#define log_catch()
Logger::get_log( "CATCH", __LINE__, __FUNCTION__ )

l'objet renvoyé est un wrapper sur un ostream qui formatte le texte et
l'envoie à l'ostream. En fonction de la compilation, il s'agit d'un ofstream
ou de std::cout.
J'ai hésité pour les macros, mais avoir __LINE__ et __FUNCTION__ (ou à
défaut __FILE__) c'est un sacré bénéfice.

--
Aurélien REGAT-BARREL

Avatar
kanze
Aurélien REGAT-BARREL wrote:
wrote:
log( log_warning ) << "warning" ;

Du coup, la fonction log() renvoie une référence au flux, et le
tour est joué.


C'est ce que j'utilise personnelement, mais via des macros.

/// log_trace() : Logger des messages de traçage
#define log_trace()
Logger::get_log( "TRACE", __LINE__, __FUNCTION__ )

/// log_error() : Logger des messages d'erreur
#define log_error()
Logger::get_log( "ERROR", __LINE__, __FUNCTION__ )

/// log_catch() : Logger les exceptions catchées
#define log_catch()
Logger::get_log( "CATCH", __LINE__, __FUNCTION__ )

l'objet renvoyé est un wrapper sur un ostream qui formatte le
texte et l'envoie à l'ostream. En fonction de la compilation,
il s'agit d'un ofstream ou de std::cout.
J'ai hésité pour les macros, mais avoir __LINE__ et
__FUNCTION__ (ou à défaut __FILE__) c'est un sacré bénéfice.


Tout à fait.

Dans l'industrie, il faut absolument que 1) l'utilisation soit
la plus simple possible, et 2) que le coût en temps d'exécution
quand les logs sont configurés inhibés soit le plus faible
possible. Sinon, personne s'en sert. Du coup, j'utilise aussi
des macro ; dans certains cas, je me suis aussi permis un
tableau global, de façon à ce que le macro devient :

#define LOG( severity )
Logger::isActive[ severity ]
&& Logger::getStream( severity, __FILE__, __LINE__ )

Puisque la séverité, c'est quasiment toujours une constante, la
première partie revient à un test immédiat sur un booléen : deux
ou trois instructions machines, maximum, en général. Je deteste
des macros comme ça, mais l'alternatif, que personne ne se sert
des logs, est encore pire.

Une ou deux fois, pour faire passer la pillule, j'ai du mettre
même les sorties de l'utilisateur en paramètre du macro, c-à-d
LOG_INFO( "x = " << x ) ;
Comme ça, je pouvais arguer que si les logs prenaient trop de
temps, on pouvait les supprimer complétement, en rédéfinant le
macro vide. Ça n'a jamais été nécessaire, mais le fait de
pouvoir le faire a aidé à convaincre des hésitants, parfois.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


1 2 3 4