]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliLog.h
Removing the coding violation
[u/mrichter/AliRoot.git] / STEER / AliLog.h
1 #ifndef ALILOG_H
2 #define ALILOG_H
3 /* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4  * See cxx source for full Copyright notice                               */
5
6 /* $Id$ */
7
8 ///
9 /// class for logging debug, info and error messages
10 ///
11
12 #include <TObject.h>
13 #include <TObjArray.h>
14 #include <TString.h>
15
16
17 class AliLog: public TObject {
18  public:
19   AliLog();
20   virtual ~AliLog();
21   static AliLog* Instance() {return fgInstance;}
22
23   enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
24   typedef void (*AliLogNotification)(EType_t type, const char* message );
25
26
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);
36
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);
47   static void  Flush();
48
49   static void  SetHandleRootMessages(Bool_t on);
50
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);
59
60   static void  SetPrintRepetitions(Bool_t on);
61
62   static void  WriteToFile(const char* name, Int_t option = 0);
63
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);
74
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);
83
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);
87
88  private:
89   AliLog(const AliLog& log);
90   AliLog& operator = (const AliLog& log);
91
92   void           ReadEnvSettings();
93
94   static void    RootErrorHandler(Int_t level, Bool_t abort, 
95                                   const char* location, const char* message);
96
97   void           CloseFile(Int_t type);
98   FILE*          GetOutputStream(Int_t type);
99
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);
105
106   void           PrintString(Int_t type, FILE* stream, const char* format, ...);
107   void           PrintRepetitions();
108
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);
113
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);
117
118   enum {kDebugOffset = kDebug-1};
119
120   static AliLog* fgInstance;                 //! pointer to current instance
121
122   static Bool_t  fgDebugEnabled;             // flag for debug en-/disabling
123
124   UInt_t         fGlobalLogLevel;            // global logging level
125   TObjArray      fModuleDebugLevels;         // debug levels for modules
126   TObjArray      fClassDebugLevels;          // debug levels for classes
127
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
132
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
137
138   Bool_t         fPrintRepetitions;          // print number of repetitions instead of repeated message on/off
139
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
149
150   ClassDef(AliLog, 1)   // class for logging debug, info and error messages
151 };
152
153
154 // module name
155 #ifdef _MODULE_
156 #define MODULENAME() _MODULE_
157 #else
158 #define MODULENAME() "NoModule"
159 #endif
160
161 // function name
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__
166 #else
167 #define FUNCTIONNAME() "???"
168 #endif
169
170 // redirection
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);}
174
175
176 // debug level
177 #ifdef LOG_NO_DEBUG
178 #define AliDebugLevel() -1
179 #define AliDebugLevelClass() -1
180 #define AliDebugLevelGeneral(scope) -1
181 #else
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)
185 #endif
186
187 // debug messages
188 #ifdef LOG_NO_DEBUG
189 #define AliDebug(level, message)
190 #define AliDebugClass(level, message)
191 #define AliDebugGeneral(scope, level, message)
192 #else
193
194 // inspired by log4cxx code (see log4cxx/Logger.h)
195 // implements GCC branch prediction for increasing logging performance
196 #if !defined(ALIROOT_UNLIKELY)
197 #if __GNUC__ >= 3
198 /**
199 Provides optimization hint to the compiler
200 to optimize for the expression being false.
201 @param expr boolean expression.
202 @returns value of expression.
203 */
204 #define ALIROOT_UNLIKELY(expr) __builtin_expect(expr, 0)
205 #else
206 /**
207 Provides optimization hint to the compiler
208 to optimize for the expression being false.
209 @param expr boolean expression.
210 @returns value of expression.
211 **/
212 #define ALIROOT_UNLIKELY(expr) expr
213 #endif
214 #endif 
215
216 /**
217 Logs a message to a specified logger with the DEBUG level.
218
219 @param logLevel the debug level.
220 @param message message to print in the following format: Form(message).
221     Note, that message should contain balanced parenthesis, like 
222     <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code> 
223 */
224 #define AliDebug(logLevel, message) \
225         do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), ClassName()) >= logLevel)) {\
226           AliLog::Debug(logLevel, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
227
228 /**
229 Logs a message to a specified logger with the DEBUG level.
230
231 @param logLevel the debug level.
232 @param message message to print in the following format: Form(message).
233     Note, that message should contain balanced parenthesis, like 
234     <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code> 
235 */
236 #define AliDebugClass(logLevel, message) \
237         do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) >= logLevel)) {\
238           AliLog::Debug(logLevel, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
239
240 /**
241 Logs a message to a specified logger with the DEBUG level.
242
243 @param scope the logging scope.
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> 
248 */
249 #define AliDebugGeneral(scope, logLevel, message) \
250         do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), scope) >= logLevel)) {\
251           AliLog::Debug(logLevel, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
252
253 #endif
254
255 // redirection to debug
256 #define StdoutToAliDebug(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, ClassName(), whatever)
257 #define StderrToAliDebug(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, ClassName(), whatever)
258 #define ToAliDebug(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, ClassName(), whatever)
259 #define StdoutToAliDebugClass(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, Class()->GetName(), whatever)
260 #define StderrToAliDebugClass(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
261 #define ToAliDebugClass(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
262 #define StdoutToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, scope, whatever)
263 #define StderrToAliDebugGeneral(scope, level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, scope, whatever)
264 #define ToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, scope, whatever)
265
266 // debug stream objects
267 #define AliDebugStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
268 #define AliDebugClassStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
269 #define AliDebugGeneralStream(scope, level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
270
271
272 // info messages
273 #ifdef LOG_NO_INFO
274 #define AliInfo(message)
275 #define AliInfoClass(message)
276 #define AliInfoGeneral(scope, message)
277 #else
278 #define AliInfo(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
279 #define AliInfoClass(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
280 #define AliInfoGeneral(scope, message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
281 #endif
282
283 // redirection to info
284 #define StdoutToAliInfo(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, ClassName(), whatever)
285 #define StderrToAliInfo(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
286 #define ToAliInfo(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
287 #define StdoutToAliInfoClass(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, Class()->GetName(), whatever)
288 #define StderrToAliInfoClass(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
289 #define ToAliInfoClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
290 #define StdoutToAliInfoGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, scope, whatever)
291 #define StderrToAliInfoGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kInfo, 0, scope, whatever)
292 #define ToAliInfoGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, scope, whatever)
293
294 // info stream objects
295 #define AliInfoStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
296 #define AliInfoClassStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
297 #define AliInfoGeneralStream(scope) AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
298
299
300 // warning messages
301 #ifdef LOG_NO_WARNING
302 #define AliWarning(message)
303 #define AliWarningClass(message)
304 #define AliWarningGeneral(scope, message)
305 #else
306 #define AliWarning(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
307 #define AliWarningClass(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
308 #define AliWarningGeneral(scope, message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
309 #endif
310
311 // redirection to warning
312 #define StdoutToAliWarning(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, ClassName(), whatever)
313 #define StderrToAliWarning(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
314 #define ToAliWarning(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
315 #define StdoutToAliWarningClass(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, Class()->GetName(), whatever)
316 #define StderrToAliWarningClass(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
317 #define ToAliWarningClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
318 #define StdoutToAliWarningGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, scope, whatever)
319 #define StderrToAliWarningGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kWarning, 0, scope, whatever)
320 #define ToAliWarningGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, scope, whatever)
321
322 // warning stream objects
323 #define AliWarningStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
324 #define AliWarningClassStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
325 #define AliWarningGeneralStream(scope) AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
326
327
328 // error messages
329 #define AliError(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
330 #define AliErrorClass(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
331 #define AliErrorGeneral(scope, message) {AliLog::Message(AliLog::kError, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
332
333 // redirection to error
334 #define StdoutToAliError(whatever) REDIRECTSTDOUT(AliLog::kError, 0, ClassName(), whatever)
335 #define StderrToAliError(whatever) REDIRECTSTDERR(AliLog::kError, 0, ClassName(), whatever)
336 #define ToAliError(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, ClassName(), whatever)
337 #define StdoutToAliErrorClass(whatever) REDIRECTSTDOUT(AliLog::kError, 0, Class()->GetName(), whatever)
338 #define StderrToAliErrorClass(whatever) REDIRECTSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
339 #define ToAliErrorClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
340 #define StdoutToAliErrorGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kError, 0, scope, whatever)
341 #define StderrToAliErrorGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kError, 0, scope, whatever)
342 #define ToAliErrorGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, scope, whatever)
343
344 // error stream objects
345 #define AliErrorStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
346 #define AliErrorClassStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
347 #define AliErrorGeneralStream(scope) AliLog::Stream(AliLog::kError, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
348
349
350 // fatal messages
351 #define AliFatal(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
352 #define AliFatalClass(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
353 #define AliFatalGeneral(scope, message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
354
355 #endif