#ifndef ALILOG_H
#define ALILOG_H
#include <TClass.h>
#include <TObjArray.h>
#include <TObject.h>
#include <TString.h>
using std::ostream;
#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
{
public:
enum EType_t {kFatal = 0, kError, kWarning, kInfo, kDebug, kMaxType};
typedef void (*AliLogNotification)(EType_t type, const char* message );
static AliLog *GetRootLogger();
static void DeleteRootLogger();
static void EnableCoreDump(Bool_t enabled);
static void MakeCoreDump(const char *fout);
static void EnableDebug(Bool_t enabled);
static void SetGlobalLogLevel(EType_t type);
static Int_t GetGlobalLogLevel();
static void SetGlobalDebugLevel(Int_t level);
static Int_t GetGlobalDebugLevel();
static void SetModuleDebugLevel(const char* module, Int_t level);
static void ClearModuleDebugLevel(const char* module);
static void SetClassDebugLevel(const char* className, Int_t level);
static void ClearClassDebugLevel(const char* className);
static void SetStandardOutput();
static void SetStandardOutput(EType_t type);
static void SetErrorOutput();
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);
static void SetPrintType(Bool_t on);
static void SetPrintType(EType_t type, Bool_t on);
static void SetPrintModule(Bool_t on);
static void SetPrintModule(EType_t type, Bool_t on);
static void SetPrintScope(Bool_t on);
static void SetPrintScope(EType_t type, Bool_t on);
static void SetPrintLocation(Bool_t on);
static void SetPrintLocation(EType_t type, Bool_t on);
static void SetPrintRepetitions(Bool_t on);
static void WriteToFile(const char* name, Int_t option = 0);
static Bool_t IsDebugEnabled() {return fgDebugEnabled;}
static Int_t GetDebugLevel(const char* module, const char* className);
static void Message(UInt_t level, const char* message,
const char* module, const char* className,
const char* function, const char* file, Int_t line);
static void Debug(UInt_t level, const char* message,
const char* module, const char* className,
const char* function, const char* file, Int_t line);
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_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_t type, UInt_t level,
const char* module, const char* className,
const char* function, const char* file, Int_t line);
static void TestException(Int_t level=10);
private:
AliLog();
virtual ~AliLog();
AliLog(const AliLog& log);
AliLog& operator = (const AliLog& log);
void ReadEnvSettings();
static void RootErrorHandler(Int_t level, Bool_t abort,
const char* location, const char* message);
void CloseFile(Int_t type);
FILE* GetOutputStream(Int_t type);
UInt_t GetLogLevel(const char* module, const char* className) const;
void PrintMessage(UInt_t type, const char* message,
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,
const char* module, const char* className,
const char* function,
const char* file, Int_t line, Bool_t print);
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;
static Bool_t fgDebugEnabled;
static Bool_t fgCoreEnabled;
UInt_t fGlobalLogLevel;
TObjArray fModuleDebugLevels;
TObjArray fClassDebugLevels;
Int_t fOutputTypes[kMaxType];
TString fFileNames[kMaxType];
FILE* fOutputFiles[kMaxType];
ostream* fOutputStreams[kMaxType];
Bool_t fPrintType[kMaxType];
Bool_t fPrintModule[kMaxType];
Bool_t fPrintScope[kMaxType];
Bool_t fPrintLocation[kMaxType];
Bool_t fPrintRepetitions;
Int_t fRepetitions;
UInt_t fLastType;
TString fLastMessage;
TString fLastModule;
TString fLastClassName;
TString fLastFunction;
TString fLastFile;
Int_t fLastLine;
AliLogNotification fCallBacks[kMaxType];
ClassDef(AliLog, 1)
};
#ifdef _MODULE_
# define MODULENAME() _MODULE_
#else
# define MODULENAME() "NoModule"
#endif
#if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
# define FUNCTIONNAME() __FUNCTION__
#else
# define FUNCTIONNAME() "???"
#endif
#define REDIRECTSTDOUT(type, level, scope, whatever) \
do {Int_t originalStdout = AliLog::RedirectStdoutTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); \
whatever; AliLog::RestoreStdout(originalStdout);} while(false)
#define REDIRECTSTDERR(type, level, scope, whatever) \
do {Int_t originalStderr = AliLog::RedirectStderrTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); \
whatever; AliLog::RestoreStderr(originalStderr);} while(false)
#define REDIRECTSTDOUTANDSTDERR(type, level, scope, whatever) \
do {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);} while(false)
#ifdef LOG_NO_DEBUG
# define AliDebugLevel() -1
# define AliDebugLevelClass() -1
# define AliDebugLevelGeneral(scope) -1
#else
# define AliDebugLevel() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), ClassName()) : -1)
# define AliDebugLevelClass() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) : -1)
# define AliDebugLevelGeneral(scope) ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(MODULENAME(), scope) : -1)
#endif
#ifdef LOG_NO_DEBUG
# define AliDebug(level, message) do { } while (false)
# define AliDebugClass(level, message) do { } while (false)
# define AliDebugGeneral(scope, level, message) do { } while (false)
# define AliDebugF(level, message,...) do { } while (false)
# define AliDebugClassF(level, message,...) do { } while (false)
# define AliDebugGeneralF(scope, level, message,...) do { } while (false)
#else
# if !defined(ALIROOT_UNLIKELY)
# if defined(__GNUC__) && (__GNUC__ >= 3)
# define ALIROOT_UNLIKELY(expr) __builtin_expect(expr, 0)
# else
# define ALIROOT_UNLIKELY(expr) expr
# endif
# endif
# 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)
# 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)
# 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)
# define AliDebugF(logLevel,format,...) \
do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), ClassName()) >= logLevel)) { \
TString m;m.Form(format,__VA_ARGS__); \
AliLog::Debug(logLevel, m, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
# define AliDebugClassF(logLevel,format,...) \
do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), Class()->GetName()) >= logLevel)) { \
TString m;m.Form(format,__VA_ARGS__); \
AliLog::Debug(logLevel, m, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
# define AliDebugGeneralF(scope,logLevel,format,...) \
do { if (ALIROOT_UNLIKELY(AliLog::IsDebugEnabled() && AliLog::GetDebugLevel(MODULENAME(), scope) >= logLevel)) { \
TString m;m.Form(format,__VA_ARGS__); \
AliLog::Debug(logLevel, m, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__); }} while (0)
#endif
#define StdoutToAliDebug(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, ClassName(), whatever)
#define StderrToAliDebug(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, ClassName(), whatever)
#define ToAliDebug(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, ClassName(), whatever)
#define StdoutToAliDebugClass(level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, Class()->GetName(), whatever)
#define StderrToAliDebugClass(level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
#define ToAliDebugClass(level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, Class()->GetName(), whatever)
#define StdoutToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUT(AliLog::kDebug, level, scope, whatever)
#define StderrToAliDebugGeneral(scope, level, whatever) REDIRECTSTDERR(AliLog::kDebug, level, scope, whatever)
#define ToAliDebugGeneral(scope, level, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kDebug, level, scope, whatever)
#define AliDebugStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliDebugClassStream(level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliDebugGeneralStream(scope, level) AliLog::Stream(AliLog::kDebug, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
#define AliMessage(lvl,message) do { \
AliLog::Message(lvl, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#define AliMessageClass(lvl,message) do { \
AliLog::Message(lvl, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#define AliMessageGeneral(scope,lvl,message) do { \
AliLog::Message(lvl, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#define AliMessageF(lvl,format,...) do { \
TString m; m.Form(format,__VA_ARGS__); \
AliLog::Message(lvl, m, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#define AliMessageClassF(lvl,format,...) do { \
TString m; m.Form(format,__VA_ARGS__); \
AliLog::Message(lvl, m, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#define AliMessageGeneralF(scope,lvl,format,...) do { \
TString m; m.Form(format,__VA_ARGS__); \
AliLog::Message(lvl, m, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);} while(false)
#ifdef LOG_NO_INFO
# define AliInfo(message) do { } while (false)
# define AliInfoClass(message) do { } while (false)
# define AliInfoGeneral(scope, message) do { } while (false)
# define AliInfoF(message,...) do { } while (false)
# define AliInfoClassF(message,...) do { } while (false)
# define AliInfoGeneralF(scope, message,...) do { } while (false)
#else
# define AliInfo(message) AliMessage(AliLog::kInfo, message)
# define AliInfoClass(message) AliMessageClass(AliLog::kInfo, message)
# define AliInfoGeneral(scope, message) AliMessageGeneral(scope, AliLog::kInfo, message)
# define AliInfoF(message,...) AliMessageF(AliLog::kInfo, message, __VA_ARGS__)
# define AliInfoClassF(message,...) AliMessageClassF(AliLog::kInfo, message, __VA_ARGS__)
# define AliInfoGeneralF(scope,message,...) AliMessageGeneralF(scope, AliLog::kInfo, message, __VA_ARGS__)
#endif
#define StdoutToAliInfo(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, ClassName(), whatever)
#define StderrToAliInfo(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
#define ToAliInfo(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, ClassName(), whatever)
#define StdoutToAliInfoClass(whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, Class()->GetName(), whatever)
#define StderrToAliInfoClass(whatever) REDIRECTSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
#define ToAliInfoClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, Class()->GetName(), whatever)
#define StdoutToAliInfoGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kInfo, 0, scope, whatever)
#define StderrToAliInfoGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kInfo, 0, scope, whatever)
#define ToAliInfoGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kInfo, 0, scope, whatever)
#define AliInfoStream() AliLog::Stream(AliLog::kInfo, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
#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__)
#ifdef LOG_NO_WARNING
# define AliWarning(message) do { } while (false)
# define AliWarningClass(message) do { } while (false)
# define AliWarningGeneral(scope, message) do { } while (false)
# define AliWarningF(message,...) do { } while (false)
# define AliWarningClassF(message,...) do { } while (false)
# define AliWarningGeneralF(scope, message,...) do { } while (false)
#else
# define AliWarning(message) AliMessage(AliLog::kWarning, message)
# define AliWarningClass(message) AliMessageClass(AliLog::kWarning, message)
# define AliWarningGeneral(scope, message) AliMessageGeneral(scope, AliLog::kWarning, message)
# define AliWarningF(message,...) AliMessageF(AliLog::kWarning, message, __VA_ARGS__)
# define AliWarningClassF(message,...) AliMessageClassF(AliLog::kWarning, message, __VA_ARGS__)
# define AliWarningGeneralF(scope,message,...) AliMessageGeneralF(scope, AliLog::kWarning, message, __VA_ARGS__)
#endif
#define StdoutToAliWarning(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, ClassName(), whatever)
#define StderrToAliWarning(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
#define ToAliWarning(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, ClassName(), whatever)
#define StdoutToAliWarningClass(whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, Class()->GetName(), whatever)
#define StderrToAliWarningClass(whatever) REDIRECTSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
#define ToAliWarningClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, Class()->GetName(), whatever)
#define StdoutToAliWarningGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kWarning, 0, scope, whatever)
#define StderrToAliWarningGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kWarning, 0, scope, whatever)
#define ToAliWarningGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kWarning, 0, scope, whatever)
#define AliWarningStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliWarningClassStream() AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliWarningGeneralStream(scope) AliLog::Stream(AliLog::kWarning, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
#define AliError(message) AliMessage(AliLog::kError, message)
#define AliErrorClass(message) AliMessageClass(AliLog::kError, message)
#define AliErrorGeneral(scope, message) AliMessageGeneral(scope, AliLog::kError, message)
#define AliErrorF(message,...) AliMessageF(AliLog::kError, message, __VA_ARGS__)
#define AliErrorClassF(message,...) AliMessageClassF(AliLog::kError, message, __VA_ARGS__)
#define AliErrorGeneralF(scope,message,...) AliMessageGeneralF(scope, AliLog::kError, message, __VA_ARGS__)
#define StdoutToAliError(whatever) REDIRECTSTDOUT(AliLog::kError, 0, ClassName(), whatever)
#define StderrToAliError(whatever) REDIRECTSTDERR(AliLog::kError, 0, ClassName(), whatever)
#define ToAliError(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, ClassName(), whatever)
#define StdoutToAliErrorClass(whatever) REDIRECTSTDOUT(AliLog::kError, 0, Class()->GetName(), whatever)
#define StderrToAliErrorClass(whatever) REDIRECTSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
#define ToAliErrorClass(whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, Class()->GetName(), whatever)
#define StdoutToAliErrorGeneral(scope, whatever) REDIRECTSTDOUT(AliLog::kError, 0, scope, whatever)
#define StderrToAliErrorGeneral(scope, whatever) REDIRECTSTDERR(AliLog::kError, 0, scope, whatever)
#define ToAliErrorGeneral(scope, whatever) REDIRECTSTDOUTANDSTDERR(AliLog::kError, 0, scope, whatever)
#define AliErrorStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliErrorClassStream() AliLog::Stream(AliLog::kError, 0, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__)
#define AliErrorGeneralStream(scope) AliLog::Stream(AliLog::kError, 0, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__)
#define AliFatal(message) AliMessage(AliLog::kFatal, message)
#define AliFatalClass(message) AliMessageClass(AliLog::kFatal, message)
#define AliFatalGeneral(scope, message) AliMessageGeneral(scope, AliLog::kFatal, message)
#define AliFatalF(message,...) AliMessageF(AliLog::kFatal, message, __VA_ARGS__)
#define AliFatalClassF(message,...) AliMessageClassF(AliLog::kFatal, message, __VA_ARGS__)
#define AliFatalGeneralF(scope,message,...) AliMessageGeneralF(scope, AliLog::kFatal, message, __VA_ARGS__)
#endif