[edit]: ceci est un fork d'une autre discussion.
r0d.
Pour un logger je serais tenter de dire Variable globale (comme std::cout).
Version imprimable
[edit]: ceci est un fork d'une autre discussion.
r0d.
Pour un logger je serais tenter de dire Variable globale (comme std::cout).
Pour une classe loggueur, le singleton me semble quand même la meilleure approche. (pourtant je suis pas un grand fan du singleton).
Attention quand même au niveau de l'ordre de destruction du singleton, il en faut un plutôt bien pensé offrant plusieurs choix de gestion de durée de vie. (et là je dis, loki ftw).
Salut,
Pour des fonctions de log par exemple, le singleton peut être masqué par des fonctions libres plus simples : trace_message, trace_erreur, trace_debug... qui ont l'avantage de pouvoir être désactivée en release.
c'est forcer de l'objet la ou il y en a pas non ?
si tu n'as qu'une instance et que tout le monde y a acces je pense que ca releve plus de la programmation sequentielle que de la programmation objet.
un logger, c'est jamais qu'un printf en gros. au lieu de te trimballer un singleton ou une instance, peut etre devrais tu publier des methodes statiques et qu'une classe (singleton) soit utilisée dans l'implémentation sans que ca se voie pour l'appelant
je veux dire, si tout le monde faitje ne vois pas pourquoi ca serait plus moche de faireCode:Logger::instance()->log("blabla");
quitte a avoir un objet logger quelque part.Code:Logger::log("blabla");
[edit]comme 3Darchi. J'arrive souvent apres la bataille ces derniers temps...
[HS]
Pour le logger, j'aime bien ajouter quelques macros, afin de pourvoir faire ça:
[/HS]Code:
1
2 LOG_WARNING << "warning message" << param; LOG_ERROR << "warning message" << param;
avec log une macro :Code:log("warning message" << param);
crée un logger temporaire, colle des trucs dedans. Libre au logger temporaire de faire ce qu'il lui chante . l'avantage c'est que tu peux complètement retirer le code en config optim.Code:
1
2#define log(msg) Logger()<< msg;
Sauf qu'une telle macro n'est pas très "safe" (essaye de mettre une ',' dedans par exemple). La manière classique d'écrire une macro de log serait plutôt :
Avec logDisabled une constante connue à la compilation, le code généré devrait être identique à rien du tout dans le cas où le log est inactif.Code:
1
2 #define LOG if(logDisabled) ; else log LOG << "Test";
je ne vois pas pourquoi c'est pas safe, qu'est ce qui se passe avec une virgule ?
Code:
1
2
3
4
5
6
7
8
9
10
11 #define TOTO(x) cout << x; template<class A, class B> int f(A a, B b) { return a*b; } int main() { TOTO(f<int, int>(3,4) << endl); }
Code:
1
2 1>main.cpp(26): warning C4002: too many actual parameters for macro 'TOTO' 1>main.cpp(26): error C2143: syntax error : missing ',' before ';'
ce sujet semble intéresser. Alors pour éviter un overflow, j'ai fais un fork de la discussion d'à côté ici.
A noter que loglite (qui me semble plutôt pas mal à permière vue) est actuellement candidate pour être intégrée à boost.
Je pense qu'il y a deux types de logs. Le log de debug que tu veux désactiver en production et le log en production dont tu as besoin parce qu'il y aura toujours un problème quelque part.
Enfin personnellement, et même si en milieu industriel on ne peut pas se permettre de mettre un programme buggé en prod, il y a toujours quelque chose qui fait que l'on a besoin de logs.
J'ai des projets où j'ai plusieurs façons de logger:
- Des logs directement dans le buffer du kernel pour des machines embarqué sous linux
- Des logs fichiers journaliers
- Des logs envoyés à un serveur distant pour être mis en base de donnée et accessible sur les outils de monitoring globaux, avec traduction etc..
Sinon pour en revenir au sujet j'ai pas mal utilisé log4cpp en singleton, avec extensions des classes existantes