3 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * See cxx source for full Copyright notice */
9 /// class for logging debug, info and error messages
13 #include <TObjArray.h>
17 class AliLog: public TObject {
21 static AliLog* Instance() {return fgInstance;}
23 enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
24 typedef void (*AliLogNotification)(EType_t type, const char* message );
27 static void EnableDebug(Bool_t enabled);
28 static void SetGlobalLogLevel(EType_t type);
29 static Int_t GetGlobalLogLevel();
30 static void SetGlobalDebugLevel(Int_t level);
31 static Int_t GetGlobalDebugLevel();
32 static void SetModuleDebugLevel(const char* module, Int_t level);
33 static void ClearModuleDebugLevel(const char* module);
34 static void SetClassDebugLevel(const char* className, Int_t level);
35 static void ClearClassDebugLevel(const char* className);
37 static void SetStandardOutput();
38 static void SetStandardOutput(EType_t type);
39 static void SetErrorOutput();
40 static void SetErrorOutput(EType_t type);
41 static void SetFileOutput(const char* fileName);
42 static void SetFileOutput(EType_t type, const char* fileName);
43 static void SetStreamOutput(ostream* stream);
44 static void SetStreamOutput(EType_t type, ostream* stream);
45 static void SetLogNotification(AliLogNotification pCallBack);
46 static void SetLogNotification(EType_t type, AliLogNotification pCallBack);
49 static void SetHandleRootMessages(Bool_t on);
51 static void SetPrintType(Bool_t on);
52 static void SetPrintType(EType_t type, Bool_t on);
53 static void SetPrintModule(Bool_t on);
54 static void SetPrintModule(EType_t type, Bool_t on);
55 static void SetPrintScope(Bool_t on);
56 static void SetPrintScope(EType_t type, Bool_t on);
57 static void SetPrintLocation(Bool_t on);
58 static void SetPrintLocation(EType_t type, Bool_t on);
60 static void SetPrintRepetitions(Bool_t on);
62 static void WriteToFile(const char* name, Int_t option = 0);
64 // the following public methods are used by the preprocessor macros
65 // and should not be called directly
66 static Bool_t IsDebugEnabled() {return fgDebugEnabled;}
67 static Int_t GetDebugLevel(const char* module, const char* className);
68 static void Message(UInt_t level, const char* message,
69 const char* module, const char* className,
70 const char* function, const char* file, Int_t line);
71 static void Debug(UInt_t level, const char* message,
72 const char* module, const char* className,
73 const char* function, const char* file, Int_t line);
75 static Int_t RedirectStdoutTo(EType_t type, UInt_t level, const char* module,
76 const char* className, const char* function,
77 const char* file, Int_t line, Bool_t print);
78 static Int_t RedirectStderrTo(EType_t type, UInt_t level, const char* module,
79 const char* className, const char* function,
80 const char* file, Int_t line, Bool_t print);
81 static void RestoreStdout(Int_t original);
82 static void RestoreStderr(Int_t original);
84 static ostream& Stream(EType_t type, UInt_t level,
85 const char* module, const char* className,
86 const char* function, const char* file, Int_t line);
89 AliLog(const AliLog& log);
90 AliLog& operator = (const AliLog& log);
92 void ReadEnvSettings();
94 static void RootErrorHandler(Int_t level, Bool_t abort,
95 const char* location, const char* message);
97 void CloseFile(Int_t type);
98 FILE* GetOutputStream(Int_t type);
100 UInt_t GetLogLevel(const char* module, const char* className) const;
101 void PrintMessage(UInt_t type, const char* message,
102 const char* module, const char* className,
103 const char* function,
104 const char* file, Int_t line);
106 void PrintString(Int_t type, FILE* stream, const char* format, ...);
107 void PrintRepetitions();
109 Int_t RedirectTo(FILE* stream, EType_t type, UInt_t level,
110 const char* module, const char* className,
111 const char* function,
112 const char* file, Int_t line, Bool_t print);
114 ostream& GetStream(EType_t type, UInt_t level,
115 const char* module, const char* className,
116 const char* function, const char* file, Int_t line);
118 enum {kDebugOffset = kDebug-1};
120 static AliLog* fgInstance; //! pointer to current instance
122 static Bool_t fgDebugEnabled; // flag for debug en-/disabling
124 UInt_t fGlobalLogLevel; // global logging level
125 TObjArray fModuleDebugLevels; // debug levels for modules
126 TObjArray fClassDebugLevels; // debug levels for classes
128 Int_t fOutputTypes[kMaxType]; // types of output streams
129 TString fFileNames[kMaxType]; // file names
130 FILE* fOutputFiles[kMaxType]; //! log output files
131 ostream* fOutputStreams[kMaxType]; //! log output streams
133 Bool_t fPrintType[kMaxType]; // print type on/off
134 Bool_t fPrintModule[kMaxType]; // print module on/off
135 Bool_t fPrintScope[kMaxType]; // print scope/class name on/off
136 Bool_t fPrintLocation[kMaxType]; // print file and line on/off
138 Bool_t fPrintRepetitions; // print number of repetitions instead of repeated message on/off
140 Int_t fRepetitions; //! counter of repetitions
141 UInt_t fLastType; //! type of last message
142 TString fLastMessage; //! last message
143 TString fLastModule; //! module name of last message
144 TString fLastClassName; //! class name of last message
145 TString fLastFunction; //! function name of last message
146 TString fLastFile; //! file name of last message
147 Int_t fLastLine; //! line number of last message
148 AliLogNotification fCallBacks[kMaxType]; //! external notification callback
150 ClassDef(AliLog, 1) // class for logging debug, info and error messages
156 #define MODULENAME() _MODULE_
158 #define MODULENAME() "NoModule"
162 #if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
163 #define FUNCTIONNAME() __FUNCTION__
164 // #elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
165 // #define FUNCTIONNAME() __FUNC__
167 #define FUNCTIONNAME() "???"
171 #define REDIRECTSTDOUT(type, level, scope, whatever) {Int_t originalStdout = AliLog::RedirectStdoutTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStdout(originalStdout);}
172 #define REDIRECTSTDERR(type, level, scope, whatever) {Int_t originalStderr = AliLog::RedirectStderrTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStderr(originalStderr);}
173 #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);}
178 #define AliDebugLevel() -1
179 #define AliDebugLevelClass() -1
180 #define AliDebugLevelGeneral(scope) -1
182 #define AliDebugLevel() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), ClassName()) : -1)
183 #define AliDebugLevelClass() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) : -1)
184 #define AliDebugLevelGeneral(scope) ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), scope) : -1)
189 #define AliDebug(level, message)
190 #define AliDebugClass(level, message)
191 #define AliDebugGeneral(scope, level, message)
194 @param N Debug level - always evaluated
195 @param A Argument Form(including paranthesis) - the message to
196 print. Note, that @a A should contain balanced paranthesis, like
198 AliDebug(1, Form("Failed to decode line %d of %s", line, filename));
200 The point is, if the current log level isn't high enough, as
201 returned by the AliLog object, then we do not want to evalute the
202 call to Form, since that is an expensive call. We should always
203 put macros like this into a @c do ... @c while loop, since that
204 makes sure that evaluations are local, and that we can safely put
205 a @c ; after the macro call. Note, that @c do ... @c while loop
206 and the call with extra paranthis, are an old tricks used by many
207 C coders (see for example Bison, the Linux kernel, and the like).
208 Christian Holm Christensen
210 #define AliDebug(N, A) \
212 if (!AliLog::IsDebugEnabled() || \
213 AliLog::GetDebugLevel(MODULENAME(), ClassName()) < N) break; \
214 AliLog::Debug(N, A, MODULENAME(), ClassName(), FUNCTIONNAME(), \
215 __FILE__, __LINE__); } while (false)
216 //#define AliDebug(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
217 #define AliDebugClass(N, A) \
219 if (!AliLog::IsDebugEnabled() || \
220 AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) < N) break; \
221 AliLog::Debug(N, A, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), \
222 __FILE__, __LINE__); } while (false)
223 //#define AliDebugClass(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
224 #define AliDebugGeneral(scope, N, A) \
226 if (!AliLog::IsDebugEnabled() || \
227 AliLog::GetDebugLevel(MODULENAME(), scope) < N) break; \
228 AliLog::Debug(N, A, MODULENAME(), scope, FUNCTIONNAME(), \
229 __FILE__, __LINE__); } while (false)
230 //#define AliDebugGeneral(scope, level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
233 // redirection to debug
234 #define StdoutToAliDebug(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, ClassName(), whatever)
235 #define StderrToAliDebug(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, ClassName(), whatever)
236 #define ToAliDebug(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, ClassName(), whatever)
237 #define StdoutToAliDebugClass(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, Class()->GetName(), whatever)
238 #define StderrToAliDebugClass(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
239 #define ToAliDebugClass(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
240 #define StdoutToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, scope, whatever)
241 #define StderrToAliDebugGeneral(scope, level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, scope, whatever)
242 #define ToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, scope, whatever)
244 // debug stream objects
245 #define AliDebugStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
246 #define AliDebugClassStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
247 #define AliDebugGeneralStream(scope, level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
252 #define AliInfo(message)
253 #define AliInfoClass(message)
254 #define AliInfoGeneral(scope, message)
256 #define AliInfo(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
257 #define AliInfoClass(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
258 #define AliInfoGeneral(scope, message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
261 // redirection to info
262 #define StdoutToAliInfo(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, ClassName(), whatever)
263 #define StderrToAliInfo(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
264 #define ToAliInfo(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
265 #define StdoutToAliInfoClass(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, Class()->GetName(), whatever)
266 #define StderrToAliInfoClass(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
267 #define ToAliInfoClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
268 #define StdoutToAliInfoGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, scope, whatever)
269 #define StderrToAliInfoGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kInfo, 0, scope, whatever)
270 #define ToAliInfoGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, scope, whatever)
272 // info stream objects
273 #define AliInfoStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
274 #define AliInfoClassStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
275 #define AliInfoGeneralStream(scope) AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
279 #ifdef LOG_NO_WARNING
280 #define AliWarning(message)
281 #define AliWarningClass(message)
282 #define AliWarningGeneral(scope, message)
284 #define AliWarning(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
285 #define AliWarningClass(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
286 #define AliWarningGeneral(scope, message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
289 // redirection to warning
290 #define StdoutToAliWarning(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, ClassName(), whatever)
291 #define StderrToAliWarning(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
292 #define ToAliWarning(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
293 #define StdoutToAliWarningClass(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, Class()->GetName(), whatever)
294 #define StderrToAliWarningClass(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
295 #define ToAliWarningClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
296 #define StdoutToAliWarningGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, scope, whatever)
297 #define StderrToAliWarningGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kWarning, 0, scope, whatever)
298 #define ToAliWarningGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, scope, whatever)
300 // warning stream objects
301 #define AliWarningStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
302 #define AliWarningClassStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
303 #define AliWarningGeneralStream(scope) AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
307 #define AliError(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
308 #define AliErrorClass(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
309 #define AliErrorGeneral(scope, message) {AliLog::Message(AliLog::kError, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
311 // redirection to error
312 #define StdoutToAliError(whatever) REDIRECTSTDOUT(AliLog::kError, 0, ClassName(), whatever)
313 #define StderrToAliError(whatever) REDIRECTSTDERR(AliLog::kError, 0, ClassName(), whatever)
314 #define ToAliError(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, ClassName(), whatever)
315 #define StdoutToAliErrorClass(whatever) REDIRECTSTDOUT(AliLog::kError, 0, Class()->GetName(), whatever)
316 #define StderrToAliErrorClass(whatever) REDIRECTSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
317 #define ToAliErrorClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
318 #define StdoutToAliErrorGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kError, 0, scope, whatever)
319 #define StderrToAliErrorGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kError, 0, scope, whatever)
320 #define ToAliErrorGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, scope, whatever)
322 // error stream objects
323 #define AliErrorStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
324 #define AliErrorClassStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
325 #define AliErrorGeneralStream(scope) AliLog::Stream(AliLog::kError, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
329 #define AliFatal(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
330 #define AliFatalClass(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
331 #define AliFatalGeneral(scope, message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}