]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/AliLog.h
Optionally the log term of Rossi parameterization for mult.scattering can be
[u/mrichter/AliRoot.git] / STEER / AliLog.h
index 4ea0926e40f9ecb583a2f314af15592e3e77b659..1155f5faae5b7d613c3f18c50eb679e0a6892a83 100644 (file)
@@ -5,25 +5,48 @@
 
 /* $Id$ */
 
-///
-/// class for logging debug, info and error messages
-///
-
-#include <TObject.h>
+#include <TClass.h>
 #include <TObjArray.h>
+#include <TObject.h>
 #include <TString.h>
 
+// deprecation macro
+#if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
+#define ALIROOT_DEPRECATED(func) func  __attribute__ ((deprecated))
+#elif defined(_MSC_VER) && _MSC_VER >= 1300
+#define ALIROOT_DEPRECATED(func) __declspec(deprecated) func
+# else
+#define ALIROOT_DEPRECATED(func) func
+#endif
 
-class AliLog: public TObject {
+/**
+ * class for logging debug, info and error messages
+ */
+class AliLog: public TObject
+{
  public:
-  AliLog();
-  virtual ~AliLog();
-  static AliLog* Instance() {return fgInstance;}
 
-  enum EType {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
+               // Log4j log levels: TRACE, DEBUG, INFO, WARN, ERROR, FATAL
+  enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
+  typedef void (*AliLogNotification)(EType_t type, const char* message );
+
+               // NB: singleton constructor & destructor should not be public!
+               // ALIROOT_DEPRECATED(AliLog());
+               // ALIROOT_DEPRECATED(virtual ~AliLog());
 
+               // NB: singleton deprecated static instance method
+               // ALIROOT_DEPRECATED(static AliLog* Instance() {return fgInstance;};)
+
+               // get root logger singleton instance
+               static AliLog *GetRootLogger();
+
+               // delete root logger singleton instance
+               static void DeleteRootLogger();
+
+               // NB: the following functions should not be static
+               // NB: deprecated: logging configuration should be made through to a configuration file
   static void  EnableDebug(Bool_t enabled);
-  static void  SetGlobalLogLevel(EType type);
+  static void  SetGlobalLogLevel(EType_t type);
   static Int_t GetGlobalLogLevel();
   static void  SetGlobalDebugLevel(Int_t level);
   static Int_t GetGlobalDebugLevel();
@@ -33,27 +56,31 @@ class AliLog: public TObject {
   static void  ClearClassDebugLevel(const char* className);
 
   static void  SetStandardOutput();
-  static void  SetStandardOutput(EType type);
+  static void  SetStandardOutput(EType_t type);
   static void  SetErrorOutput();
-  static void  SetErrorOutput(EType type);
+  static void  SetErrorOutput(EType_t type);
   static void  SetFileOutput(const char* fileName);
-  static void  SetFileOutput(EType type, const char* fileName);
+  static void  SetFileOutput(EType_t type, const char* fileName);
+  static void  SetStreamOutput(ostream* stream);
+  static void  SetStreamOutput(EType_t type, ostream* stream);
+  static void  SetLogNotification(AliLogNotification pCallBack);
+  static void  SetLogNotification(EType_t type, AliLogNotification pCallBack);
   static void  Flush();
 
   static void  SetHandleRootMessages(Bool_t on);
 
   static void  SetPrintType(Bool_t on);
-  static void  SetPrintType(EType type, Bool_t on);
+  static void  SetPrintType(EType_t type, Bool_t on);
   static void  SetPrintModule(Bool_t on);
-  static void  SetPrintModule(EType type, Bool_t on);
+  static void  SetPrintModule(EType_t type, Bool_t on);
   static void  SetPrintScope(Bool_t on);
-  static void  SetPrintScope(EType type, Bool_t on);
+  static void  SetPrintScope(EType_t type, Bool_t on);
   static void  SetPrintLocation(Bool_t on);
-  static void  SetPrintLocation(EType type, Bool_t on);
+  static void  SetPrintLocation(EType_t type, Bool_t on);
 
   static void  SetPrintRepetitions(Bool_t on);
 
-  static void  Write(const char* name, Int_t option = 0);
+  static void  WriteToFile(const char* name, Int_t option = 0);
 
   // the following public methods are used by the preprocessor macros 
   // and should not be called directly
@@ -66,20 +93,26 @@ class AliLog: public TObject {
                      const char* module, const char* className,
                      const char* function, const char* file, Int_t line);
 
-  static Int_t RedirectStdoutTo(EType type, UInt_t level, const char* module, 
+  static Int_t RedirectStdoutTo(EType_t type, UInt_t level, const char* module, 
                                 const char* className, const char* function,
                                 const char* file, Int_t line, Bool_t print);
-  static Int_t RedirectStderrTo(EType type, UInt_t level, const char* module, 
+  static Int_t RedirectStderrTo(EType_t type, UInt_t level, const char* module, 
                                 const char* className, const char* function,
                                 const char* file, Int_t line, Bool_t print);
   static void  RestoreStdout(Int_t original);
   static void  RestoreStderr(Int_t original);
 
-  static ostream& Stream(EType type, UInt_t level,
+  static ostream& Stream(EType_t type, UInt_t level,
                          const char* module, const char* className,
                          const char* function, const char* file, Int_t line);
 
  private:
+
+               // constructor is made private for implementing a singleton
+               AliLog();
+               virtual ~AliLog();
+
+               // NOT IMPLEMENTED?
   AliLog(const AliLog& log);
   AliLog& operator = (const AliLog& log);
 
@@ -96,21 +129,22 @@ class AliLog: public TObject {
                               const char* module, const char* className,
                               const char* function, 
                               const char* file, Int_t line);
+
+  void           PrintString(Int_t type, FILE* stream, const char* format, ...);
   void           PrintRepetitions();
 
-  Int_t          RedirectTo(FILE* stream, EType type, UInt_t level,
+  Int_t          RedirectTo(FILE* stream, EType_t type, UInt_t level,
                             const char* module, const char* className,
                             const char* function,
                             const char* file, Int_t line, Bool_t print);
 
-  ostream&       GetStream(EType type, UInt_t level,
+  ostream&       GetStream(EType_t type, UInt_t level,
                            const char* module, const char* className,
                            const char* function, const char* file, Int_t line);
 
   enum {kDebugOffset = kDebug-1};
 
   static AliLog* fgInstance;                 //! pointer to current instance
-
   static Bool_t  fgDebugEnabled;             // flag for debug en-/disabling
 
   UInt_t         fGlobalLogLevel;            // global logging level
@@ -120,7 +154,7 @@ class AliLog: public TObject {
   Int_t          fOutputTypes[kMaxType];     // types of output streams
   TString        fFileNames[kMaxType];       // file names
   FILE*          fOutputFiles[kMaxType];     //! log output files
-  ofstream*      fOutputStreams[kMaxType];   //! log output streams
+  ostream*       fOutputStreams[kMaxType];   //! log output streams
 
   Bool_t         fPrintType[kMaxType];       // print type on/off
   Bool_t         fPrintModule[kMaxType];     // print module on/off
@@ -137,23 +171,24 @@ class AliLog: public TObject {
   TString        fLastFunction;              //! function name of last message
   TString        fLastFile;                  //! file name of last message
   Int_t          fLastLine;                  //! line number of last message
+  AliLogNotification fCallBacks[kMaxType];   //! external notification callback
 
   ClassDef(AliLog, 1)   // class for logging debug, info and error messages
 };
 
 
-// module name
-#ifdef __MODULE__
-#define MODULENAME() __MODULE__
+// module name macro
+#ifdef _MODULE_
+#define MODULENAME() _MODULE_
 #else
 #define MODULENAME() "NoModule"
 #endif
 
-// function name
+// function name macro
 #if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
 #define FUNCTIONNAME() __FUNCTION__
-#elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
-#define FUNCTIONNAME() __FUNC__
+// #elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
+// #define FUNCTIONNAME() __FUNC__
 #else
 #define FUNCTIONNAME() "???"
 #endif
@@ -181,9 +216,66 @@ class AliLog: public TObject {
 #define AliDebugClass(level, message)
 #define AliDebugGeneral(scope, level, message)
 #else
-#define AliDebug(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
-#define AliDebugClass(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
-#define AliDebugGeneral(scope, level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
+
+// inspired by log4cxx code (see log4cxx/Logger.h)
+// implements GCC branch prediction for increasing logging performance
+#if !defined(ALIROOT_UNLIKELY)
+#if defined(__GNUC__) && (__GNUC__ >= 3)
+/**
+Provides optimization hint to the compiler
+to optimize for the expression being false.
+@param expr boolean expression.
+@returns value of expression.
+*/
+#define ALIROOT_UNLIKELY(expr) __builtin_expect(expr, 0)
+#else
+/**
+Provides optimization hint to the compiler
+to optimize for the expression being false.
+@param expr boolean expression.
+@returns value of expression.
+**/
+#define ALIROOT_UNLIKELY(expr) expr
+#endif
+#endif 
+
+/**
+Logs a message to a specified logger with the DEBUG level.
+
+@param logLevel the debug level.
+@param message message to print in the following format: Form(message).
+    Note, that message should contain balanced parenthesis, like 
+    <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code> 
+*/
+#define AliDebug(logLevel, message) \
+        do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), ClassName()) >= logLevel)) {\
+         AliLog::Debug(logLevel, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
+
+/**
+Logs a message to a specified logger with the DEBUG level.
+
+@param logLevel the debug level.
+@param message message to print in the following format: Form(message).
+    Note, that message should contain balanced parenthesis, like 
+    <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code> 
+*/
+#define AliDebugClass(logLevel, message) \
+       do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) >= logLevel)) {\
+         AliLog::Debug(logLevel, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
+
+/**
+Logs a message to a specified logger with the DEBUG level.
+
+@param scope the logging scope.
+@param logLevel the debug level.
+@param message message to print in the following format: Form(message).
+    Note, that message should contain balanced parenthesis, like 
+    <code>AliDebug(1, Form("Failed to decode line %d of %s", line, filename));</code> 
+*/
+#define AliDebugGeneral(scope, logLevel, message) \
+       do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), scope) >= logLevel)) {\
+         AliLog::Debug(logLevel, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
+
 #endif
 
 // redirection to debug
@@ -230,7 +322,6 @@ class AliLog: public TObject {
 #define AliInfoClassStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
 #define AliInfoGeneralStream(scope) AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
 
-
 // warning messages
 #ifdef LOG_NO_WARNING
 #define AliWarning(message)