X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STEER%2FAliLog.h;h=1155f5faae5b7d613c3f18c50eb679e0a6892a83;hb=8f7b1226e6156cef90cac09edaf8b085c8e6f503;hp=b3d828be58cfd6242bb9ad4aa76f408cfb755716;hpb=44ce6bbe7bd3d0907578777227bea6e8db483261;p=u%2Fmrichter%2FAliRoot.git diff --git a/STEER/AliLog.h b/STEER/AliLog.h index b3d828be58c..1155f5faae5 100644 --- a/STEER/AliLog.h +++ b/STEER/AliLog.h @@ -5,23 +5,46 @@ /* $Id$ */ -/// -/// class for logging debug, info and error messages -/// - -#include +#include #include +#include #include +// 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;} + // 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_t type); static Int_t GetGlobalLogLevel(); @@ -38,6 +61,10 @@ class AliLog: public TObject { static void SetErrorOutput(EType_t type); static void SetFileOutput(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); @@ -80,6 +107,12 @@ class AliLog: public TObject { 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,6 +129,8 @@ 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_t type, UInt_t level, @@ -110,7 +145,6 @@ class AliLog: public TObject { 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,19 +171,20 @@ 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) @@ -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 + AliDebug(1, Form("Failed to decode line %d of %s", line, filename)); +*/ +#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 + AliDebug(1, Form("Failed to decode line %d of %s", line, filename)); +*/ +#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 + AliDebug(1, Form("Failed to decode line %d of %s", line, filename)); +*/ +#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)