Fixes for bug #52499: Field polarities inconsistiency
[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 /** @defn AliDebug 
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 
197     @verbatim 
198       AliDebug(1, Form("Failed to decode line %d of %s", line, filename));
199     @endverbatim 
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
209 */
210 #define AliDebug(N, A) \
211   do { \
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) \
218   do { \
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) \
225   do { \
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__);}
231 #endif
232
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)
243
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__)
248
249
250 // info messages
251 #ifdef LOG_NO_INFO
252 #define AliInfo(message)
253 #define AliInfoClass(message)
254 #define AliInfoGeneral(scope, message)
255 #else
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__);}
259 #endif
260
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)
271
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__)
276
277
278 // warning messages
279 #ifdef LOG_NO_WARNING
280 #define AliWarning(message)
281 #define AliWarningClass(message)
282 #define AliWarningGeneral(scope, message)
283 #else
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__);}
287 #endif
288
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)
299
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__)
304
305
306 // error messages
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__);}
310
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)
321
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__)
326
327
328 // fatal messages
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__);}
332
333 #endif