X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=STEER%2FAliLog.h;h=1155f5faae5b7d613c3f18c50eb679e0a6892a83;hb=8f7b1226e6156cef90cac09edaf8b085c8e6f503;hp=a68f40b79282a54981c893376c8aa6d07318c943;hpb=eeb769e29adcba903642b3362362704905e0ff92;p=u%2Fmrichter%2FAliRoot.git diff --git a/STEER/AliLog.h b/STEER/AliLog.h index a68f40b7928..1155f5faae5 100644 --- a/STEER/AliLog.h +++ b/STEER/AliLog.h @@ -5,25 +5,48 @@ /* $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;} - 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,25 +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 Write(const char* name, Int_t option = 0); + static void SetPrintRepetitions(Bool_t on); + + 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 @@ -64,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); @@ -95,19 +130,21 @@ class AliLog: public TObject { const char* function, const char* file, Int_t line); - Int_t RedirectTo(FILE* stream, EType type, UInt_t level, + void PrintString(Int_t type, FILE* stream, const char* format, ...); + void PrintRepetitions(); + + 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 @@ -117,29 +154,41 @@ 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 Bool_t fPrintScope[kMaxType]; // print scope/class name on/off Bool_t fPrintLocation[kMaxType]; // print file and line on/off + Bool_t fPrintRepetitions; // print number of repetitions instead of repeated message on/off + + Int_t fRepetitions; //! counter of repetitions + UInt_t fLastType; //! type of last message + TString fLastMessage; //! last message + TString fLastModule; //! module name of last message + TString fLastClassName; //! class name of last message + 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 @@ -167,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 @@ -216,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)