3 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * See cxx source for full Copyright notice */
13 #if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
14 #define ALIROOT_DEPRECATED(func) func __attribute__ ((deprecated))
15 #elif defined(_MSC_VER) && _MSC_VER >= 1300
16 #define ALIROOT_DEPRECATED(func) __declspec(deprecated) func
18 #define ALIROOT_DEPRECATED(func) func
22 * class for logging debug, info and error messages
24 class AliLog: public TObject
28 // Log4j log levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
29 enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
30 typedef void (*AliLogNotification)(EType_t type, const char* message );
32 // NB: singleton constructor & destructor should not be public!
33 // ALIROOT_DEPRECATED(AliLog());
34 // ALIROOT_DEPRECATED(virtual ~AliLog());
36 // NB: singleton deprecated static instance method
37 // ALIROOT_DEPRECATED(static AliLog* Instance() {return fgInstance;};)
39 // get root logger singleton instance
40 static AliLog *GetRootLogger();
42 // delete root logger singleton instance
43 static void DeleteRootLogger();
45 // NB: the following functions should not be static
46 // NB: deprecated: logging configuration should be made through to a configuration file
47 static void EnableDebug(Bool_t enabled);
48 static void SetGlobalLogLevel(EType_t type);
49 static Int_t GetGlobalLogLevel();
50 static void SetGlobalDebugLevel(Int_t level);
51 static Int_t GetGlobalDebugLevel();
52 static void SetModuleDebugLevel(const char* module, Int_t level);
53 static void ClearModuleDebugLevel(const char* module);
54 static void SetClassDebugLevel(const char* className, Int_t level);
55 static void ClearClassDebugLevel(const char* className);
57 static void SetStandardOutput();
58 static void SetStandardOutput(EType_t type);
59 static void SetErrorOutput();
60 static void SetErrorOutput(EType_t type);
61 static void SetFileOutput(const char* fileName);
62 static void SetFileOutput(EType_t type, const char* fileName);
63 static void SetStreamOutput(ostream* stream);
64 static void SetStreamOutput(EType_t type, ostream* stream);
65 static void SetLogNotification(AliLogNotification pCallBack);
66 static void SetLogNotification(EType_t type, AliLogNotification pCallBack);
69 static void SetHandleRootMessages(Bool_t on);
71 static void SetPrintType(Bool_t on);
72 static void SetPrintType(EType_t type, Bool_t on);
73 static void SetPrintModule(Bool_t on);
74 static void SetPrintModule(EType_t type, Bool_t on);
75 static void SetPrintScope(Bool_t on);
76 static void SetPrintScope(EType_t type, Bool_t on);
77 static void SetPrintLocation(Bool_t on);
78 static void SetPrintLocation(EType_t type, Bool_t on);
80 static void SetPrintRepetitions(Bool_t on);
82 static void WriteToFile(const char* name, Int_t option = 0);
84 // the following public methods are used by the preprocessor macros
85 // and should not be called directly
86 static Bool_t IsDebugEnabled() {return fgDebugEnabled;}
87 static Int_t GetDebugLevel(const char* module, const char* className);
88 static void Message(UInt_t level, const char* message,
89 const char* module, const char* className,
90 const char* function, const char* file, Int_t line);
91 static void Debug(UInt_t level, const char* message,
92 const char* module, const char* className,
93 const char* function, const char* file, Int_t line);
95 static Int_t RedirectStdoutTo(EType_t type, UInt_t level, const char* module,
96 const char* className, const char* function,
97 const char* file, Int_t line, Bool_t print);
98 static Int_t RedirectStderrTo(EType_t type, UInt_t level, const char* module,
99 const char* className, const char* function,
100 const char* file, Int_t line, Bool_t print);
101 static void RestoreStdout(Int_t original);
102 static void RestoreStderr(Int_t original);
104 static ostream& Stream(EType_t type, UInt_t level,
105 const char* module, const char* className,
106 const char* function, const char* file, Int_t line);
110 // constructor is made private for implementing a singleton
115 AliLog(const AliLog& log);
116 AliLog& operator = (const AliLog& log);
118 void ReadEnvSettings();
120 static void RootErrorHandler(Int_t level, Bool_t abort,
121 const char* location, const char* message);
123 void CloseFile(Int_t type);
124 FILE* GetOutputStream(Int_t type);
126 UInt_t GetLogLevel(const char* module, const char* className) const;
127 void PrintMessage(UInt_t type, const char* message,
128 const char* module, const char* className,
129 const char* function,
130 const char* file, Int_t line);
132 void PrintString(Int_t type, FILE* stream, const char* format, ...);
133 void PrintRepetitions();
135 Int_t RedirectTo(FILE* stream, EType_t type, UInt_t level,
136 const char* module, const char* className,
137 const char* function,
138 const char* file, Int_t line, Bool_t print);
140 ostream& GetStream(EType_t type, UInt_t level,
141 const char* module, const char* className,
142 const char* function, const char* file, Int_t line);
144 enum {kDebugOffset = kDebug-1};
146 static AliLog* fgInstance; //! pointer to current instance
147 static Bool_t fgDebugEnabled; // flag for debug en-/disabling
149 UInt_t fGlobalLogLevel; // global logging level
150 TObjArray fModuleDebugLevels; // debug levels for modules
151 TObjArray fClassDebugLevels; // debug levels for classes
153 Int_t fOutputTypes[kMaxType]; // types of output streams
154 TString fFileNames[kMaxType]; // file names
155 FILE* fOutputFiles[kMaxType]; //! log output files
156 ostream* fOutputStreams[kMaxType]; //! log output streams
158 Bool_t fPrintType[kMaxType]; // print type on/off
159 Bool_t fPrintModule[kMaxType]; // print module on/off
160 Bool_t fPrintScope[kMaxType]; // print scope/class name on/off
161 Bool_t fPrintLocation[kMaxType]; // print file and line on/off
163 Bool_t fPrintRepetitions; // print number of repetitions instead of repeated message on/off
165 Int_t fRepetitions; //! counter of repetitions
166 UInt_t fLastType; //! type of last message
167 TString fLastMessage; //! last message
168 TString fLastModule; //! module name of last message
169 TString fLastClassName; //! class name of last message
170 TString fLastFunction; //! function name of last message
171 TString fLastFile; //! file name of last message
172 Int_t fLastLine; //! line number of last message
173 AliLogNotification fCallBacks[kMaxType]; //! external notification callback
175 ClassDef(AliLog, 1) // class for logging debug, info and error messages
181 #define MODULENAME() _MODULE_
183 #define MODULENAME() "NoModule"
186 // function name macro
187 #if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
188 #define FUNCTIONNAME() __FUNCTION__
189 // #elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
190 // #define FUNCTIONNAME() __FUNC__
192 #define FUNCTIONNAME() "???"
196 #define REDIRECTSTDOUT(type, level, scope, whatever) {Int_t originalStdout = AliLog::RedirectStdoutTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStdout(originalStdout);}
197 #define REDIRECTSTDERR(type, level, scope, whatever) {Int_t originalStderr = AliLog::RedirectStderrTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStderr(originalStderr);}
198 #define REDIRECTSTDOUTANDSTDERR(type, level, scope, whatever) {Int_t originalStdout = AliLog::RedirectStdoutTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); Int_t originalStderr = AliLog::RedirectStderrTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStderr(originalStderr); AliLog::RestoreStdout(originalStdout);}
203 #define AliDebugLevel() -1
204 #define AliDebugLevelClass() -1
205 #define AliDebugLevelGeneral(scope) -1
207 #define AliDebugLevel() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), ClassName()) : -1)
208 #define AliDebugLevelClass() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) : -1)
209 #define AliDebugLevelGeneral(scope) ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), scope) : -1)
214 #define AliDebug(level, message)
215 #define AliDebugClass(level, message)
216 #define AliDebugGeneral(scope, level, message)
219 // inspired by log4cxx code (see log4cxx/Logger.h)
220 // implements GCC branch prediction for increasing logging performance
221 #if !defined(ALIROOT_UNLIKELY)
222 #if defined(__GNUC__) && (__GNUC__ >= 3)
224 Provides optimization hint to the compiler
225 to optimize for the expression being false.
226 @param expr boolean expression.
227 @returns value of expression.
229 #define ALIROOT_UNLIKELY(expr) __builtin_expect(expr, 0)
232 Provides optimization hint to the compiler
233 to optimize for the expression being false.
234 @param expr boolean expression.
235 @returns value of expression.
237 #define ALIROOT_UNLIKELY(expr) expr
242 Logs a message to a specified logger with the DEBUG level.
244 @param logLevel the debug level.
245 @param message message to print in the following format: Form(message).
246 Note, that message should contain balanced parenthesis, like
247 <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code>
249 #define AliDebug(logLevel, message) \
250 do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), ClassName()) >= logLevel)) {\
251 AliLog::Debug(logLevel, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
254 Logs a message to a specified logger with the DEBUG level.
256 @param logLevel the debug level.
257 @param message message to print in the following format: Form(message).
258 Note, that message should contain balanced parenthesis, like
259 <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code>
261 #define AliDebugClass(logLevel, message) \
262 do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) >= logLevel)) {\
263 AliLog::Debug(logLevel, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
266 Logs a message to a specified logger with the DEBUG level.
268 @param scope the logging scope.
269 @param logLevel the debug level.
270 @param message message to print in the following format: Form(message).
271 Note, that message should contain balanced parenthesis, like
272 <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code>
274 #define AliDebugGeneral(scope, logLevel, message) \
275 do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), scope) >= logLevel)) {\
276 AliLog::Debug(logLevel, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
280 // redirection to debug
281 #define StdoutToAliDebug(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, ClassName(), whatever)
282 #define StderrToAliDebug(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, ClassName(), whatever)
283 #define ToAliDebug(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, ClassName(), whatever)
284 #define StdoutToAliDebugClass(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, Class()->GetName(), whatever)
285 #define StderrToAliDebugClass(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
286 #define ToAliDebugClass(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
287 #define StdoutToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, scope, whatever)
288 #define StderrToAliDebugGeneral(scope, level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, scope, whatever)
289 #define ToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, scope, whatever)
291 // debug stream objects
292 #define AliDebugStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
293 #define AliDebugClassStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
294 #define AliDebugGeneralStream(scope, level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
299 #define AliInfo(message)
300 #define AliInfoClass(message)
301 #define AliInfoGeneral(scope, message)
303 #define AliInfo(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
304 #define AliInfoClass(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
305 #define AliInfoGeneral(scope, message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
308 // redirection to info
309 #define StdoutToAliInfo(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, ClassName(), whatever)
310 #define StderrToAliInfo(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
311 #define ToAliInfo(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
312 #define StdoutToAliInfoClass(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, Class()->GetName(), whatever)
313 #define StderrToAliInfoClass(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
314 #define ToAliInfoClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
315 #define StdoutToAliInfoGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, scope, whatever)
316 #define StderrToAliInfoGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kInfo, 0, scope, whatever)
317 #define ToAliInfoGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, scope, whatever)
319 // info stream objects
320 #define AliInfoStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
321 #define AliInfoClassStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
322 #define AliInfoGeneralStream(scope) AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
325 #ifdef LOG_NO_WARNING
326 #define AliWarning(message)
327 #define AliWarningClass(message)
328 #define AliWarningGeneral(scope, message)
330 #define AliWarning(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
331 #define AliWarningClass(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
332 #define AliWarningGeneral(scope, message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
335 // redirection to warning
336 #define StdoutToAliWarning(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, ClassName(), whatever)
337 #define StderrToAliWarning(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
338 #define ToAliWarning(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
339 #define StdoutToAliWarningClass(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, Class()->GetName(), whatever)
340 #define StderrToAliWarningClass(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
341 #define ToAliWarningClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
342 #define StdoutToAliWarningGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, scope, whatever)
343 #define StderrToAliWarningGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kWarning, 0, scope, whatever)
344 #define ToAliWarningGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, scope, whatever)
346 // warning stream objects
347 #define AliWarningStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
348 #define AliWarningClassStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
349 #define AliWarningGeneralStream(scope) AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
353 #define AliError(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
354 #define AliErrorClass(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
355 #define AliErrorGeneral(scope, message) {AliLog::Message(AliLog::kError, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
357 // redirection to error
358 #define StdoutToAliError(whatever) REDIRECTSTDOUT(AliLog::kError, 0, ClassName(), whatever)
359 #define StderrToAliError(whatever) REDIRECTSTDERR(AliLog::kError, 0, ClassName(), whatever)
360 #define ToAliError(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, ClassName(), whatever)
361 #define StdoutToAliErrorClass(whatever) REDIRECTSTDOUT(AliLog::kError, 0, Class()->GetName(), whatever)
362 #define StderrToAliErrorClass(whatever) REDIRECTSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
363 #define ToAliErrorClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
364 #define StdoutToAliErrorGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kError, 0, scope, whatever)
365 #define StderrToAliErrorGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kError, 0, scope, whatever)
366 #define ToAliErrorGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, scope, whatever)
368 // error stream objects
369 #define AliErrorStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
370 #define AliErrorClassStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
371 #define AliErrorGeneralStream(scope) AliLog::Stream(AliLog::kError, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
375 #define AliFatal(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
376 #define AliFatalClass(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
377 #define AliFatalGeneral(scope, message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}