]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/AliHLTLogging.h
introducing variadic free HLT logging macros. When including AliHLTLoggingVariadicFre...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTLogging.h
1 //-*- Mode: C++ -*-
2 // $Id$
3
4 #ifndef ALIHLTLOGGING_H
5 #define ALIHLTLOGGING_H
6 /* This file is property of and copyright by the ALICE HLT Project        * 
7  * ALICE Experiment at CERN, All rights reserved.                         *
8  * See cxx source for full Copyright notice                               */
9
10 /** @file   AliHLTLogging.h
11     @author Matthias Richter, Timm Steinbeck
12     @date   
13     @brief  HLT module logging primitives.
14 */
15
16 #include "AliHLTDataTypes.h"
17 #include "AliHLTStdIncludes.h"
18 #include "TString.h"
19 #include "TObject.h"
20 #include "TArrayC.h"
21
22 class AliHLTComponentHandler;
23 //#define LOG_PREFIX ""       // logging prefix, for later extensions
24
25 #define ALILOG_WRAPPER_LIBRARY "libHLTrec.so"
26
27 /* the logging macros can be used inside methods of classes which inherit from 
28  * AliHLTLogging
29  */
30 // HLTMessage is not filtered
31 #define HLTMessage( ... )   LoggingVarargs(kHLTLogNone,      NULL , NULL , __FILE__ , __LINE__ , __VA_ARGS__ )
32
33 // function name
34 #if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
35 #define FUNCTIONNAME() __FUNCTION__
36 #else
37 #define FUNCTIONNAME() "???"
38 #endif
39
40 // the following macros are filtered by the Global and Local Log Filter
41 #ifndef ALIHLTLOGGINGVARIADICFREE_H
42 #define HLTBenchmark( ... ) LoggingVarargs(kHLTLogBenchmark, Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
43 #ifdef __DEBUG
44 #define HLTDebug( ... )     if (CheckFilter(kHLTLogDebug) && CheckGroup(Class_Name())) LoggingVarargs(kHLTLogDebug,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
45 #else
46 #define HLTDebug( ... )
47 #endif
48 #define HLTInfo( ... )      if (CheckFilter(kHLTLogInfo))    LoggingVarargs(kHLTLogInfo,      Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
49 #define HLTWarning( ... )   if (CheckFilter(kHLTLogWarning)) LoggingVarargs(kHLTLogWarning,   Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
50 #define HLTError( ... )     if (CheckFilter(kHLTLogError))   LoggingVarargs(kHLTLogError,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
51 #define HLTFatal( ... )     if (CheckFilter(kHLTLogFatal))   LoggingVarargs(kHLTLogFatal,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
52 #define HLTImportant( ... ) if (CheckFilter(kHLTLogImportant))LoggingVarargs(kHLTLogImportant,Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , __VA_ARGS__ )
53
54 // the same macros are defined variadic free, in that case the message must be complete
55 // include AliHLTLoggingVariadicFree.h
56 #else //ALIHLTLOGGINGVARIADICFREE_H
57 #define HLTBenchmark( message ) LoggingVarargs(kHLTLogBenchmark, Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
58 #ifdef __DEBUG
59 #define HLTDebug( message )     if (CheckFilter(kHLTLogDebug) && CheckGroup(Class_Name())) LoggingVarargs(kHLTLogDebug,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
60 #else
61 #define HLTDebug( message )
62 #endif
63 #define HLTInfo( message )      if (CheckFilter(kHLTLogInfo))    LoggingVarargs(kHLTLogInfo,      Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
64 #define HLTWarning( message )   if (CheckFilter(kHLTLogWarning)) LoggingVarargs(kHLTLogWarning,   Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
65 #define HLTError( message )     if (CheckFilter(kHLTLogError))   LoggingVarargs(kHLTLogError,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
66 #define HLTFatal( message )     if (CheckFilter(kHLTLogFatal))   LoggingVarargs(kHLTLogFatal,     Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
67 #define HLTImportant( message ) if (CheckFilter(kHLTLogImportant))LoggingVarargs(kHLTLogImportant,Class_Name() , FUNCTIONNAME() , __FILE__ , __LINE__ , message )
68 #endif //ALIHLTLOGGINGVARIADICFREE_H
69
70 // helper macro to set the keyword
71 #define HLTLogKeyword(a)    AliHLTKeyword hltlogTmpkey(this, a)
72
73 #define HLT_DEFAULT_LOG_KEYWORD "no key"
74
75 /**
76  * @class AliHLTLogging
77  * Basic logging class. All classes inherit the besic HLT logging functionality.
78  * Logging levels are controlled by a global logging filter and a local logging
79  * filter.
80  * 
81  * @section alihlt_logging_levels Logging Levels
82  * Logging levels are switched by a bit pattern,  AliHLTComponentLogSeverity {
83  * - ::kHLTLogNone no logging (0)
84  * - ::kHLTLogBenchmark benchmark messages (0x1)
85  * - ::kHLTLogDebug debug messages (0x2)
86  * - ::kHLTLogInfo info messages (0x4)
87  * - ::kHLTLogWarning warning messages (0x8)
88  * - ::kHLTLogError error messages (0x10)
89  * - ::kHLTLogFatal fatal error messages (0x20)
90  * - ::kHLTLogImportant few important messages not to be filtered out (0x40)
91  * - ::kHLTLogAll special value to enable all messages (0x7f)
92  * - ::kHLTLogDefault the default logging level: Warning, Error, Fatal, Important (0x79)
93  *
94  * @section alihlt_logging_filter Logging Filters
95  * The class provides a global and a local logging filter, the AND beween both
96  * defines whether a message is printed or not.
97  *
98  * The global filter is by default set to ::kHLTLogAll. Please note that AliHLTSystem
99  * changes the global logging level to ::kHLTLogDefault. The global filter can be
100  * adjusted by means of SetGlobalLoggingLevel().
101  *
102  * The local filter is set to ::kHLTLogAll and can be adjusted by
103  * SetLocalLoggingLevel(). The default can be changed for all objects by
104  * SetLocalLoggingDefault(). Please note that a change of the default level only
105  * applies to objects generated after the change of the default.
106  *
107  * @section alihlt_logging_external Redirection
108  * - external logging function
109  * - keyword
110  *
111  * @section alihlt_logging_aliroot AliRoot Redirection
112  * - switching of redirection
113  * - logging options in AliSimulation/AliReconstruction
114  *
115  * @ingroup alihlt_component
116  */
117 class AliHLTLogging {
118 public:
119   AliHLTLogging();
120   AliHLTLogging(const AliHLTLogging&);
121   AliHLTLogging& operator=(const AliHLTLogging&);
122   virtual ~AliHLTLogging();
123
124   /** set the default key word
125    * the keyword is intended to simplify the use of logging macros
126    */ 
127   void SetDefaultKeyword(const char* keyword) { fpDefaultKeyword=keyword; }
128
129   /**
130    * Set a temporary keyword
131    * returns the old key value
132    */
133   const char* SetKeyword(const char* keyword) 
134     { 
135       const char* currentKeyword=fpCurrentKeyword;
136       fpCurrentKeyword=keyword;
137       return currentKeyword; 
138     }
139
140   /**
141    * Get the current keyword
142    */
143   const char* GetKeyword() const
144     {
145       if (fpCurrentKeyword) return fpCurrentKeyword;
146       else if (fpDefaultKeyword) return fpDefaultKeyword;
147       return HLT_DEFAULT_LOG_KEYWORD;
148     }
149   
150   /**
151    * Init the AliLogging class for use from external package.
152    * This initializes the logging callback. <br>
153    * Only deployed by external users of the C wrapper interface, not used
154    * when running in AliRoot
155    */
156   static int Init(AliHLTfctLogging pFun);
157
158   /**
159    * Init the message trap in AliLog.
160    * This initializes the AliLog trap, the AliLog class is the logging
161    * mechanism of AliRoot. The trap can fetch log messages written to
162    * AliLog, components and detector algorithms can use the AliLog
163    * mechanism to be as close as possible to Offline habits. <br>
164    * Only used with external users of the C wrapper interface, not used
165    * when running in AliRoot
166    */
167   static int InitAliLogTrap(AliHLTComponentHandler* pHandler);
168
169   /**
170    * Init the AliRoot logging function.
171    * All log messages are redirected to AliLog when running in AliRoot.
172    * Note: when running in PubSub, AliLog messages are redirected to PubSub,
173    * see AliHLTLogging::InitAliLogTrap
174    */
175   static int InitAliLogFunc(AliHLTComponentHandler* pHandler);
176
177   /**
178    * Genaral logging function
179    */
180   int Logging( AliHLTComponentLogSeverity severity, const char* origin, const char* keyword, const char* message, ... );
181
182   /**
183    * Logging function with two origin parameters, used by the log macros
184    */
185   virtual int LoggingVarargs(AliHLTComponentLogSeverity severity, 
186                              const char* originClass, const char* originFunc,
187                              const char* file, int line, ... ) const;
188
189   /**
190    * Send formatted string to the different channels
191    */
192   int SendMessage(AliHLTComponentLogSeverity severity, 
193                   const char* originClass, const char* originFunc,
194                   const char* file, int line,
195                   const char* message) const;
196
197   /**
198    * Evaluate the group of the debug message from the class name.
199    * @return 1 if message should be printed
200    */
201   int CheckGroup(const char* originClass) const;
202
203   /**
204    * Set the black list of classes.
205    * If the white list is set, debug messages are skipped for
206    * all classes matching one of the regular expressions in the string.
207    */
208   static int SetBlackList(const char* classnames);
209
210   /**
211    * Set the white list of classes.
212    * If the white list is set, debug messages are only printed for
213    * classes matching one of the regular expressions in the string.
214    */
215   static int SetWhiteList(const char* classnames);
216
217   /**
218    * Apply filter
219    * @return 1 if message should pass
220    */
221   int CheckFilter(AliHLTComponentLogSeverity severity) const;
222
223   /**
224    * Set global logging level
225    * logging filter for all objects
226    */
227   static void SetGlobalLoggingLevel(AliHLTComponentLogSeverity level);
228
229   /**
230    * Get global logging level
231    * logging filter for all objects
232    */
233   static AliHLTComponentLogSeverity GetGlobalLoggingLevel();
234
235   /**
236    * Set local logging level
237    * logging filter for individual object
238    */
239   virtual void SetLocalLoggingLevel(AliHLTComponentLogSeverity level);
240
241   /**
242    * Set local logging default
243    * Default logging filter for individual objects.
244    */
245   static void SetLocalLoggingDefault(AliHLTComponentLogSeverity level);
246
247   /**
248    * Get local logging level
249    * logging filter for individual object
250    */
251   AliHLTComponentLogSeverity GetLocalLoggingLevel();
252
253   /**
254    * Print message to stdout
255    */
256   static int Message(void * param, AliHLTComponentLogSeverity severity, const char* origin, const char* keyword, const char* message);
257
258   /**
259    * Build the log string from format specifier and variadac arguments
260    * @param format     format string of printf style
261    * @param ap         opened and initialized argument list
262    * @param bAppend    append to current content
263    * @return const char string with the formatted message 
264    */
265   static const char* BuildLogString(const char *format, va_list ap, bool bAppend=false);
266
267   /**
268    * Set the log string from format specifier and from variable arguments.
269    * @param format     format string of printf style
270    * @return const char string with the formatted message 
271    */
272   static const char* SetLogString(const char *format, ... );
273
274   /**
275    * Get parameter given by the external caller.
276    * This functionality is not yet implemented. It is intended
277    * to pass the parameter pointer given to the component at
278    * initialization back to the caller.
279    */
280   virtual void* GetParameter() const {return NULL;}
281
282   /**
283    * Switch logging through AliLog on or off
284    * @param sw          1 = logging through AliLog
285    */
286   void SwitchAliLog(int sw) {fgUseAliLog=(sw!=0);}
287
288   /** target stream for AliRoot logging methods */
289   static ostringstream fgLogstr;                                   //! transient
290
291   /** 
292    * The message function for dynamic use.
293    * In order to avoid dependencies on AliRoot libraries, libHLTbase loads
294    * the library dynamically and looks for the symbol.
295    */
296   typedef int (*AliHLTDynamicMessage)(AliHLTComponentLogSeverity severity, 
297                                       const char* originClass, 
298                                       const char* originFunc,
299                                       const char* file, int line, 
300                                       const char* message); 
301
302   /**
303    * The init function of the message callback for dynamic use.
304    * In order to avoid dependencies on AliRoot libraries, libHLTbase loads
305    * the library dynamically and looks for the symbol.
306    */
307   typedef int (*InitAliDynamicMessageCallback)();
308   
309 protected:
310   /** the AliRoot logging function */
311   static AliHLTDynamicMessage fgAliLoggingFunc;                    //! transient
312
313 private:
314   /** the global logging filter */
315   static  AliHLTComponentLogSeverity fgGlobalLogFilter;            // see above
316   /** the local logging filter for one class */
317   AliHLTComponentLogSeverity fLocalLogFilter;                      // see above
318   /** the global logging filter */
319   static  AliHLTComponentLogSeverity fgLocalLogDefault;            // see above
320   /** logging callback from the framework */
321   static AliHLTfctLogging fgLoggingFunc;                           // see above
322   /** default keyword */
323   const char* fpDefaultKeyword;                                    //! transient
324   /** current keyword */
325   const char* fpCurrentKeyword;                                    //! transient
326   /** switch for logging through AliLog, default on */
327   static int fgUseAliLog;                                          // see above
328   /**
329    * The global logging buffer.
330    * The buffer is created with an initial size and grown dynamically on
331    * demand.
332    */
333   static TArrayC fgAliHLTLoggingTarget;                            //! transient
334   
335   /** the maximum size of the buffer */
336   static const int fgkALIHLTLOGGINGMAXBUFFERSIZE;                  //! transient
337
338   /** groups of classes not to print debug messages */
339   static TString fgBlackList;                                      //! transient
340   
341   /** groups of classes not to print debug messages */
342   static TString fgWhiteList;                                      //! transient
343   
344   ClassDef(AliHLTLogging, 3)
345 };
346
347 /* the class AliHLTKeyword is a simple helper class used by the HLTLogKeyword macro
348  * HLTLogKeyword("a keyword") creates an object of AliHLTKeyword which sets the keyword for the logging class
349  * the object is destroyed automatically when the current scope is left and so the keyword is set
350  * to the original value
351  */
352 class AliHLTKeyword {
353  public:
354   AliHLTKeyword()
355     :
356     fpParent(NULL),
357     fpOriginal(NULL)
358     {
359     }
360
361   AliHLTKeyword(AliHLTLogging* parent, const char* keyword)
362     :
363     fpParent(parent),
364     fpOriginal(NULL)
365     {
366       if (parent) {
367         fpOriginal=fpParent->SetKeyword(keyword);
368       }
369     }
370
371   AliHLTKeyword(const AliHLTKeyword& kw)
372     :
373     fpParent(kw.fpParent),
374     fpOriginal(kw.fpOriginal)
375     {
376     }
377
378   AliHLTKeyword& operator=(const AliHLTKeyword& kw)
379     { 
380       fpParent=kw.fpParent;
381       fpOriginal=kw.fpOriginal;
382       return *this;
383     }
384
385   ~AliHLTKeyword()
386     {
387       if (fpParent) {
388         fpParent->SetKeyword(fpOriginal);
389       }
390     }
391
392  private:
393   AliHLTLogging* fpParent;                                         //! transient
394   const char* fpOriginal;                                          //! transient
395 };
396 #endif
397