]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliLog.h
Adding extra checks to protect from fatal aborts.
[u/mrichter/AliRoot.git] / STEER / AliLog.h
CommitLineData
6ab674bd 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
17class AliLog: public TObject {
18 public:
19 AliLog();
20 virtual ~AliLog();
21 static AliLog* Instance() {return fgInstance;}
22
44ce6bbe 23 enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
1948744e 24 typedef void (*AliLogNotification)(EType_t type, const char* message );
25
6ab674bd 26
27 static void EnableDebug(Bool_t enabled);
44ce6bbe 28 static void SetGlobalLogLevel(EType_t type);
6ab674bd 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();
44ce6bbe 38 static void SetStandardOutput(EType_t type);
6ab674bd 39 static void SetErrorOutput();
44ce6bbe 40 static void SetErrorOutput(EType_t type);
6ab674bd 41 static void SetFileOutput(const char* fileName);
44ce6bbe 42 static void SetFileOutput(EType_t type, const char* fileName);
1948744e 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);
6ab674bd 47 static void Flush();
48
49 static void SetHandleRootMessages(Bool_t on);
50
51 static void SetPrintType(Bool_t on);
44ce6bbe 52 static void SetPrintType(EType_t type, Bool_t on);
6ab674bd 53 static void SetPrintModule(Bool_t on);
44ce6bbe 54 static void SetPrintModule(EType_t type, Bool_t on);
6ab674bd 55 static void SetPrintScope(Bool_t on);
44ce6bbe 56 static void SetPrintScope(EType_t type, Bool_t on);
6ab674bd 57 static void SetPrintLocation(Bool_t on);
44ce6bbe 58 static void SetPrintLocation(EType_t type, Bool_t on);
6ab674bd 59
45fa0297 60 static void SetPrintRepetitions(Bool_t on);
61
c4cb6153 62 static void WriteToFile(const char* name, Int_t option = 0);
6ab674bd 63
64 // the following public methods are used by the preprocessor macros
65 // and should not be called directly
20848f77 66 static Bool_t IsDebugEnabled() {return fgDebugEnabled;}
6ab674bd 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
44ce6bbe 75 static Int_t RedirectStdoutTo(EType_t type, UInt_t level, const char* module,
eeb769e2 76 const char* className, const char* function,
77 const char* file, Int_t line, Bool_t print);
44ce6bbe 78 static Int_t RedirectStderrTo(EType_t type, UInt_t level, const char* module,
eeb769e2 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
44ce6bbe 84 static ostream& Stream(EType_t type, UInt_t level,
eeb769e2 85 const char* module, const char* className,
86 const char* function, const char* file, Int_t line);
87
6ab674bd 88 private:
89 AliLog(const AliLog& log);
90 AliLog& operator = (const AliLog& log);
91
eeb769e2 92 void ReadEnvSettings();
93
6ab674bd 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;
eeb769e2 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);
1948744e 105
106 void PrintString(Int_t type, FILE* stream, const char* format, ...);
45fa0297 107 void PrintRepetitions();
eeb769e2 108
44ce6bbe 109 Int_t RedirectTo(FILE* stream, EType_t type, UInt_t level,
eeb769e2 110 const char* module, const char* className,
111 const char* function,
112 const char* file, Int_t line, Bool_t print);
113
44ce6bbe 114 ostream& GetStream(EType_t type, UInt_t level,
eeb769e2 115 const char* module, const char* className,
116 const char* function, const char* file, Int_t line);
6ab674bd 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
1948744e 131 ostream* fOutputStreams[kMaxType]; //! log output streams
6ab674bd 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
45fa0297 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
1948744e 148 AliLogNotification fCallBacks[kMaxType]; //! external notification callback
45fa0297 149
6ab674bd 150 ClassDef(AliLog, 1) // class for logging debug, info and error messages
151};
152
eeb769e2 153
154// module name
eb5bc777 155#ifdef _MODULE_
156#define MODULENAME() _MODULE_
eeb769e2 157#else
158#define MODULENAME() "NoModule"
cd676389 159#endif
eeb769e2 160
161// function name
162#if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
163#define FUNCTIONNAME() __FUNCTION__
92154bc0 164// #elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
165// #define FUNCTIONNAME() __FUNC__
eeb769e2 166#else
167#define FUNCTIONNAME() "???"
cd676389 168#endif
6ab674bd 169
eeb769e2 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
6ab674bd 177#ifdef LOG_NO_DEBUG
178#define AliDebugLevel() -1
179#define AliDebugLevelClass() -1
180#define AliDebugLevelGeneral(scope) -1
181#else
eeb769e2 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)
6ab674bd 185#endif
186
eeb769e2 187// debug messages
6ab674bd 188#ifdef LOG_NO_DEBUG
189#define AliDebug(level, message)
190#define AliDebugClass(level, message)
191#define AliDebugGeneral(scope, level, message)
192#else
c2deee9d 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/**
199Provides optimization hint to the compiler
200to 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/**
207Provides optimization hint to the compiler
208to 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/**
217Logs 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>
267f939c 223*/
c2deee9d 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/**
229Logs 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/**
241Logs 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
6ab674bd 253#endif
254
eeb769e2 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
6ab674bd 273#ifdef LOG_NO_INFO
274#define AliInfo(message)
275#define AliInfoClass(message)
276#define AliInfoGeneral(scope, message)
277#else
eeb769e2 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__);}
6ab674bd 281#endif
282
eeb769e2 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
6ab674bd 301#ifdef LOG_NO_WARNING
302#define AliWarning(message)
303#define AliWarningClass(message)
304#define AliWarningGeneral(scope, message)
305#else
eeb769e2 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__);}
6ab674bd 309#endif
310
eeb769e2 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
6ab674bd 349
eeb769e2 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__);}
6ab674bd 354
355#endif