redirection and C++ streams added
authortkuhr <tkuhr@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 26 Aug 2004 09:09:30 +0000 (09:09 +0000)
committertkuhr <tkuhr@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 26 Aug 2004 09:09:30 +0000 (09:09 +0000)
STEER/AliLog.cxx
STEER/AliLog.h

index 40b6496..e3e86df 100644 (file)
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 
+#include <Riostream.h>
 #include <TError.h>
 #include <TNamed.h>
 #include <TSystem.h>
+#include <TEnv.h>
 
 #include "AliLog.h"
 
@@ -58,6 +60,7 @@ AliLog::AliLog() :
     fOutputTypes[iType] = 0;
     fFileNames[iType] = "";
     fOutputFiles[iType] = NULL;
+    fOutputStreams[iType] = NULL;
 
     fPrintType[iType] = kTRUE;
     fPrintModule[iType] = kFALSE;
@@ -70,6 +73,9 @@ AliLog::AliLog() :
   // replace the previous instance by this one
   if (fgInstance) delete fgInstance;
   fgInstance = this;
+
+  // read the .rootrc settings
+  ReadEnvSettings();
 }
 
 //_____________________________________________________________________________
@@ -115,6 +121,151 @@ AliLog& AliLog::operator = (const AliLog& /*log*/)
 
 
 //_____________________________________________________________________________
+void AliLog::ReadEnvSettings()
+{
+// load settings from the root configuration file (.rootrc)
+// and from environment variables
+
+  static const char* typeNames[kMaxType] = 
+    {"kFatal", "kError", "kWarning", "kInfo", "kDebug"};
+
+  // debug en- or disabling
+  if (gSystem->Getenv("LOG_NO_DEBUG")) {
+    fgDebugEnabled = kFALSE;
+  } else if (gEnv->Defined("AliRoot.AliLog.EnableDebug")) {
+    fgDebugEnabled = gEnv->GetValue("AliRoot.AliLog.EnableDebug", 
+                                    fgDebugEnabled);
+    AliInfo(Form("debug %sabled", ((fgDebugEnabled) ? "en" : "dis")));
+  }
+
+  // global log level
+  if (gEnv->Defined("AliRoot.AliLog.GlobalLogLevel")) {
+    const char* type = gEnv->GetValue("AliRoot.AliLog.GlobalLogLevel", "");
+    for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+      if (strcmp(type, typeNames[iType]) == 0) fGlobalLogLevel = iType;
+    }
+    AliDebug(3, Form("global log level set to %d", fGlobalLogLevel));
+  }
+
+  // global debug level
+  if (gEnv->Defined("AliRoot.AliLog.GlobalDebugLevel")) {
+    Int_t level = gEnv->GetValue("AliRoot.AliLog.GlobalDebugLevel",
+                                 Int_t(fGlobalLogLevel - kDebugOffset));
+    if (level < -kDebugOffset) level = kDebugOffset;
+    fGlobalLogLevel = kDebugOffset + level;
+    AliDebug(3, Form("global debug level set to %d",
+                    fGlobalLogLevel - kDebugOffset));
+  }
+
+  // module debug level
+  if (gEnv->Defined("AliRoot.AliLog.ModuleDebugLevel")) {
+    TString levels = gEnv->GetValue("AliRoot.AliLog.ModuleDebugLevel", "");
+    char* p = const_cast<char*>(levels.Data());
+    while (const char* module = strtok(p, " ")) {
+      p = NULL;
+      char* pos = index(module, ':');
+      if (!pos) continue;
+      *(pos++) = '\0';
+      Int_t level = atoi(pos);
+      SetModuleDebugLevel(module, level);
+      AliDebug(3, Form("debug level for module %s set to %d", module, level));
+    }
+  }
+
+  // class debug level
+  if (gEnv->Defined("AliRoot.AliLog.ClassDebugLevel")) {
+    TString levels = gEnv->GetValue("AliRoot.AliLog.ClassDebugLevel", "");
+    char* p = const_cast<char*>(levels.Data());
+    while (const char* className = strtok(p, " ")) {
+      p = NULL;
+      char* pos = index(className, ':');
+      if (!pos) continue;
+      *(pos++) = '\0';
+      Int_t level = atoi(pos);
+      SetClassDebugLevel(className, level);
+      AliDebug(3, Form("debug level for class %s set to %d", 
+                       className, level));
+    }
+  }
+
+  // general output stream
+  if (gEnv->Defined("AliRoot.AliLog.Output")) {
+    TString stream = gEnv->GetValue("AliRoot.AliLog.Output", "Standard");
+    if (stream.CompareTo("standard", TString::kIgnoreCase) == 0) {
+      SetStandardOutput();
+      AliDebug(3, "output stream set to standard output for all types");
+    } else if (stream.CompareTo("error", TString::kIgnoreCase) == 0) {
+      SetErrorOutput();
+      AliDebug(3, "output stream set to error output for all types");
+    } else if (!stream.IsNull()) {
+      SetFileOutput(stream);
+      AliDebug(3, Form("output stream set to file %s for all types", 
+                       stream.Data()));
+    }
+  }
+
+  // individual output streams
+  for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+    TString name("AliRoot.AliLog.Output.");
+    name += &typeNames[iType][1];
+    if (gEnv->Defined(name)) {
+      TString stream = gEnv->GetValue(name, "Standard");
+      if (stream.CompareTo("standard", TString::kIgnoreCase) == 0) {
+        SetStandardOutput(EType(iType));
+        AliDebug(3, Form("output stream set to standard output for type %s",
+                         typeNames[iType]));
+      } else if (stream.CompareTo("error", TString::kIgnoreCase) == 0) {
+        SetErrorOutput(EType(iType));
+        AliDebug(3, Form("output stream set to error output for type %s",
+                         typeNames[iType]));
+      } else if (!stream.IsNull()) {
+        SetFileOutput(EType(iType), stream);
+        AliDebug(3, Form("output stream set to file %s for type %s", 
+                         stream.Data(), typeNames[iType]));
+      }
+    }
+  }
+
+  // handling of root error messages
+  if (gEnv->Defined("AliRoot.AliLog.HandleRootMessages")) {
+    Bool_t on = gEnv->GetValue("AliRoot.AliLog.HandleRootMessages", kTRUE);
+    SetHandleRootMessages(on);
+    AliDebug(3, Form("handling of root messages %sabled",
+                     ((on) ? "en" : "dis")));
+  }
+
+  // printout settings
+  static const char* settingNames[4] = 
+    {"Type", "Module", "Scope", "Location"};
+  Bool_t* settings[] = 
+    {fPrintType, fPrintModule, fPrintScope, fPrintLocation};
+  for (Int_t iSetting = 0; iSetting < 4; iSetting++) {
+    TString name("AliRoot.AliLog.Print");
+    name += settingNames[iSetting];
+    if (gEnv->Defined(name)) {
+      Bool_t on = gEnv->GetValue(name, settings[iSetting][0]);
+      for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+        settings[iSetting][iType] = on;
+      }
+      AliDebug(3, Form("printing of %s %sabled for all types",
+                       settingNames[iSetting], ((on) ? "en" : "dis")));
+    }
+
+    for (Int_t iType = kFatal; iType < kMaxType; iType++) {
+      TString nameType = name + "." + &typeNames[iType][1];
+      if (gEnv->Defined(nameType)) {
+        Bool_t on = gEnv->GetValue(nameType, settings[iSetting][iType]);
+        settings[iSetting][iType] = on;
+        AliDebug(3, Form("printing of %s %sabled for type %s",
+                         settingNames[iSetting], ((on) ? "en" : "dis"),
+                         typeNames[iType]));
+      }
+    }
+  }
+}
+
+
+//_____________________________________________________________________________
 void AliLog::RootErrorHandler(Int_t level, Bool_t abort, 
                              const char* location, const char* message)
 {
@@ -299,6 +450,7 @@ void AliLog::SetFileOutput(const char* fileName)
     fgInstance->fOutputTypes[iType] = 2;
     fgInstance->fFileNames[iType] = fileName;
     fgInstance->fOutputFiles[iType] = NULL;
+    fgInstance->fOutputStreams[iType] = NULL;
   }
 }
 
@@ -316,6 +468,7 @@ void AliLog::SetFileOutput(EType type, const char* fileName)
   fgInstance->fOutputTypes[type] = 2;
   fgInstance->fFileNames[type] = fileName;
   fgInstance->fOutputFiles[type] = NULL;
+  fgInstance->fOutputStreams[type] = NULL;
 }
 
 //_____________________________________________________________________________
@@ -330,9 +483,14 @@ void AliLog::CloseFile(Int_t type)
        closeFile = kFALSE;
       }
     }
-    if (closeFile) fclose(fOutputFiles[type]);
+    if (closeFile) {
+      fclose(fOutputFiles[type]);
+      fOutputStreams[type]->close();
+      delete fOutputStreams[type];
+    }
   }
   fOutputFiles[type] = NULL;
+  fOutputStreams[type] = NULL;
   fFileNames[type] = "";
   fOutputTypes[type] = 0;
 }
@@ -342,23 +500,30 @@ FILE* AliLog::GetOutputStream(Int_t type)
 {
 // get the output stream for the given type of messages
 
+  if (type > kDebug) type = kDebug;
   if (fOutputTypes[type] == 0) return stdout;
   else if (fOutputTypes[type] == 1) return stderr;
   else if (fOutputTypes[type] == 2) {
     if (!fOutputFiles[type]) {
       FILE* file = NULL;
+      ofstream* stream = NULL;
       if (!fFileNames[type].IsNull()) {
        for (Int_t iType = kFatal; iType < kMaxType; iType++) {
          if ((iType != type) && 
              (fFileNames[iType].CompareTo(fFileNames[type]) == 0) &&
              fOutputFiles[iType]) {
            file = fOutputFiles[iType];
+           stream = fOutputStreams[iType];
            break;
          }
        }
-       if (!file) file = fopen(fFileNames[type], "a");
+       if (!file) {
+         file = fopen(fFileNames[type], "a");
+         stream = new ofstream(fFileNames[type], ios::app);
+       }
       }
       fOutputFiles[type] = file;
+      fOutputStreams[type] = stream;
       if (!file) CloseFile(type);
     }
     if (fOutputFiles[type]) return fOutputFiles[type];
@@ -376,6 +541,7 @@ void AliLog::Flush()
   for (Int_t iType = kFatal; iType < kMaxType; iType++) {
     if (fgInstance->fOutputFiles[iType]) {
       fflush(fgInstance->fOutputFiles[iType]);
+      fgInstance->fOutputStreams[iType]->flush();
     }
   }
   fflush(stderr);
@@ -517,6 +683,42 @@ Int_t AliLog::GetDebugLevel(const char* module, const char* className)
 }
 
 //_____________________________________________________________________________
+void AliLog::PrintMessage(UInt_t type, const char* message, 
+                          const char* module, const char* className,
+                          const char* function, const char* file, Int_t line)
+{
+// print the given message
+
+  FILE* stream = GetOutputStream(type);
+  static const char* typeNames[kMaxType] = 
+    {"Fatal", "Error", "Warning", "Info", "Debug"};
+
+  if (fPrintType[type]) {
+    fprintf(stream, "%s in ", typeNames[type]);
+  }
+  fprintf(stream, "<");
+  if (fPrintModule[type] && module) {
+    fprintf(stream, "%s/", module);
+  }
+  if (fPrintScope[type] && className) {
+    fprintf(stream, "%s::", className);
+  }
+  if (message) {
+    fprintf(stream, "%s>: %s", function, message);
+  } else {
+    fprintf(stream, "%s>", function);
+  }
+  if (fPrintLocation[type] && file) {
+    fprintf(stream, " (%s:%.0d)", file, line);
+  }
+  if (message) {
+    fprintf(stream, "\n");
+  } else {
+    fprintf(stream, ": ");
+  }
+}
+
+//_____________________________________________________________________________
 void AliLog::Message(UInt_t level, const char* message, 
                     const char* module, const char* className,
                     const char* function, const char* file, Int_t line)
@@ -526,28 +728,13 @@ void AliLog::Message(UInt_t level, const char* message,
   if (!fgInstance) new AliLog;
 
   // get the message type
-  static const char* typeNames[kMaxType] = 
-    {"Fatal", "Error", "Warning", "Info", "Debug"};
   UInt_t type = level;
   if (type >= kMaxType) type = kMaxType - 1;
 
   // print the message if the debug level allows
   if (level <= fgInstance->GetLogLevel(module, className)) {
-    if (fgInstance->fPrintType[type]) {
-      fprintf(fgInstance->GetOutputStream(type), "%s in ", typeNames[type]);
-    }
-    fprintf(fgInstance->GetOutputStream(type), "<");
-    if (fgInstance->fPrintModule[type] && module) {
-      fprintf(fgInstance->GetOutputStream(type), "%s/", module);
-    }
-    if (fgInstance->fPrintScope[type] && className) {
-      fprintf(fgInstance->GetOutputStream(type), "%s::", className);
-    }
-    fprintf(fgInstance->GetOutputStream(type), "%s>: %s", function, message);
-    if (fgInstance->fPrintLocation[type] && file) {
-      fprintf(fgInstance->GetOutputStream(type), " (%s:%.0d)", file, line);
-    }
-    fprintf(fgInstance->GetOutputStream(type), "\n");
+    fgInstance->PrintMessage(type, message, 
+                             module, className, function, file, line);
   }
 
   // abort in case of a fatal message
@@ -573,3 +760,126 @@ void AliLog::Debug(UInt_t level, const char* message,
   level += kDebugOffset;
   Message(level, message, module, className, function, file, line);
 }
+
+
+//_____________________________________________________________________________
+Int_t AliLog::RedirectStdoutTo(EType type, UInt_t level, const char* module, 
+                               const char* className, const char* function,
+                               const char* file, Int_t line, Bool_t print)
+{
+// redirect the standard output to the stream of the given type
+
+  if (!fgInstance) new AliLog;
+  return fgInstance->RedirectTo(stdout, type, level, module, className, 
+                                function, file, line, print);
+}
+
+//_____________________________________________________________________________
+Int_t AliLog::RedirectStderrTo(EType type, UInt_t level, const char* module, 
+                               const char* className, const char* function,
+                               const char* file, Int_t line, Bool_t print)
+{
+// redirect the standard error output to the stream of the given type
+
+  if (!fgInstance) new AliLog;
+  return fgInstance->RedirectTo(stderr, type, level, module, className, 
+                                function, file, line, print);
+}
+
+//_____________________________________________________________________________
+Int_t AliLog::RedirectTo(FILE* stream, EType type, UInt_t level, 
+                         const char* module, const char* className,
+                         const char* function, const char* file, Int_t line,
+                        Bool_t print)
+{
+// redirect the standard (error) output stream to the stream of the given type
+
+  // get the original file descriptor to be able to restore it later
+  Int_t original = dup(fileno(stream));
+  fflush(stream);
+
+  // flush the stream of the selected type
+  FILE* newStream = GetOutputStream(type);
+  fflush(newStream);
+
+  // redirect stream
+  if ((type == kDebug) && (level > 0)) level--;
+  if (type + level > GetLogLevel(module, className)) { // /dev/null
+    freopen("/dev/null", "a", stream);
+  } else if (fOutputTypes[type] == 0) {         // stdout
+    if (stream != stdout) dup2(fileno(stdout), fileno(stream));
+  } else if (fOutputTypes[type] == 1) {         // stderr
+    if (stream != stderr) dup2(fileno(stderr), fileno(stream));
+  } else if (fOutputTypes[type] == 2) {         // file
+    freopen(fFileNames[type], "a", stream);
+  }
+
+  // print information
+  if (print) {
+    PrintMessage(type, NULL, module, className, function, file, line);
+    fflush(newStream);
+  }
+
+  return original;
+}
+
+//_____________________________________________________________________________
+void AliLog::RestoreStdout(Int_t original)
+{
+// restore the standard output
+
+  fflush(stdout);
+  dup2(original, fileno(stdout));  
+}
+
+//_____________________________________________________________________________
+void AliLog::RestoreStderr(Int_t original)
+{
+// restore the standard error output
+
+  fflush(stderr);
+  dup2(original, fileno(stderr));  
+}
+
+
+//_____________________________________________________________________________
+ostream& AliLog::Stream(EType type, UInt_t level,
+                        const char* module, const char* className,
+                        const char* function, const char* file, Int_t line)
+{
+// get the stream object for the given output type
+
+  if (!fgInstance) new AliLog;
+  return fgInstance->GetStream(type, level, module, className, 
+                               function, file, line);
+}
+
+//_____________________________________________________________________________
+ostream& AliLog::GetStream(EType type, UInt_t level,
+                           const char* module, const char* className,
+                           const char* function, const char* file, Int_t line)
+{
+// get the stream object for the given output type
+
+  if ((type == kDebug) && (level > 0)) level--;
+  Bool_t noOutput = (type + level > GetLogLevel(module, className));
+
+  if (!noOutput) {
+    PrintMessage(type, NULL, module, className, function, file, line);
+  }
+  fflush(GetOutputStream(type));
+
+  static ofstream nullStream("/dev/null");
+  if (noOutput) {
+    return nullStream;
+  } else if (fOutputTypes[type] == 0) {
+    return cout;
+  } else if (fOutputTypes[type] == 1) {
+    return cerr;
+  } else if (fOutputTypes[type] == 2) {
+    return *fOutputStreams[type];
+  }
+
+  return nullStream;
+}
+
index 22c7e08..a68f40b 100644 (file)
@@ -64,10 +64,25 @@ 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, 
+                                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, 
+                                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,
+                         const char* module, const char* className,
+                         const char* function, const char* file, Int_t line);
+
  private:
   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);
 
@@ -75,6 +90,19 @@ class AliLog: public TObject {
   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);
+
+  Int_t          RedirectTo(FILE* stream, EType 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,
+                           const char* module, const char* className,
+                           const char* function, const char* file, Int_t line);
 
   enum {kDebugOffset = kDebug-1};
 
@@ -89,6 +117,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
 
   Bool_t         fPrintType[kMaxType];       // print type on/off
   Bool_t         fPrintModule[kMaxType];     // print module on/off
@@ -98,58 +127,149 @@ class AliLog: public TObject {
   ClassDef(AliLog, 1)   // class for logging debug, info and error messages
 };
 
-#ifndef __GNUC__
-#ifndef __APPLE__
-#define __FUNCTION__ "???"
+
+// module name
+#ifdef __MODULE__
+#define MODULENAME() __MODULE__
+#else
+#define MODULENAME() "NoModule"
 #endif
+
+// function name
+#if defined(__GNUC__) || defined(__ICC) || defined(__ECC) || defined(__APPLE__)
+#define FUNCTIONNAME() __FUNCTION__
+#elif defined(__HP_aCC) || defined(__alpha) || defined(__DECCXX)
+#define FUNCTIONNAME() __FUNC__
+#else
+#define FUNCTIONNAME() "???"
 #endif
 
+// redirection
+#define REDIRECTSTDOUT(type, level, scope, whatever) {Int_t originalStdout = AliLog::RedirectStdoutTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStdout(originalStdout);}
+#define REDIRECTSTDERR(type, level, scope, whatever) {Int_t originalStderr = AliLog::RedirectStderrTo(type, level, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__, kFALSE); whatever; AliLog::RestoreStderr(originalStderr);}
+#define REDIRECTSTDOUTANDSTDERR(type, level, scope, whatever) {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);}
+
+
+// debug level
 #ifdef LOG_NO_DEBUG
 #define AliDebugLevel() -1
 #define AliDebugLevelClass() -1
 #define AliDebugLevelGeneral(scope) -1
 #else
-#define AliDebugLevel() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(__MODULE__, ClassName()) : -1)
-#define AliDebugLevelClass() ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(__MODULE__, Class()->GetName()) : -1)
-#define AliDebugLevelGeneral(scope) ((AliLog::IsDebugEnabled()) ? AliLog::GetDebugLevel(__MODULE__, scope) : -1)
+#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
 
+// debug messages
 #ifdef LOG_NO_DEBUG
 #define AliDebug(level, message)
 #define AliDebugClass(level, message)
 #define AliDebugGeneral(scope, level, message)
 #else
-#define AliDebug(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, __MODULE__, ClassName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliDebugClass(level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, __MODULE__, Class()->GetName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliDebugGeneral(scope, level, message) {if (AliLog::IsDebugEnabled()) AliLog::Debug(level, message, __MODULE__, scope, __FUNCTION__, __FILE__, __LINE__);}
+#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__);}
 #endif
 
+// redirection to debug
+#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)
+
+// debug stream objects
+#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__)
+
+
+// info messages
 #ifdef LOG_NO_INFO
 #define AliInfo(message)
 #define AliInfoClass(message)
 #define AliInfoGeneral(scope, message)
 #else
-#define AliInfo(message) {AliLog::Message(AliLog::kInfo, message, __MODULE__, ClassName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliInfoClass(message) {AliLog::Message(AliLog::kInfo, message, __MODULE__, Class()->GetName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliInfoGeneral(scope, message) {AliLog::Message(AliLog::kInfo, message, __MODULE__, scope, __FUNCTION__, __FILE__, __LINE__);}
+#define AliInfo(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliInfoClass(message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliInfoGeneral(scope, message) {AliLog::Message(AliLog::kInfo, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
 #endif
 
+// redirection to info
+#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)
+
+// info stream objects
+#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__)
+
+
+// warning messages
 #ifdef LOG_NO_WARNING
 #define AliWarning(message)
 #define AliWarningClass(message)
 #define AliWarningGeneral(scope, message)
 #else
-#define AliWarning(message) {AliLog::Message(AliLog::kWarning, message, __MODULE__, ClassName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliWarningClass(message) {AliLog::Message(AliLog::kWarning, message, __MODULE__, Class()->GetName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliWarningGeneral(scope, message) {AliLog::Message(AliLog::kWarning, message, __MODULE__, scope, __FUNCTION__, __FILE__, __LINE__);}
+#define AliWarning(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliWarningClass(message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliWarningGeneral(scope, message) {AliLog::Message(AliLog::kWarning, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
 #endif
 
-#define AliError(message) {AliLog::Message(AliLog::kError, message, __MODULE__, ClassName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliErrorClass(message) {AliLog::Message(AliLog::kError, message, __MODULE__, Class()->GetName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliErrorGeneral(scope, message) {AliLog::Message(AliLog::kError, message, __MODULE__, scope, __FUNCTION__, __FILE__, __LINE__);}
+// redirection to warning
+#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)
+
+// warning stream objects
+#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__)
+
+
+// error messages
+#define AliError(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliErrorClass(message) {AliLog::Message(AliLog::kError, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliErrorGeneral(scope, message) {AliLog::Message(AliLog::kError, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
+
+// redirection to error
+#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)
+
+// error stream objects
+#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) {AliLog::Message(AliLog::kFatal, message, __MODULE__, ClassName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliFatalClass(message) {AliLog::Message(AliLog::kFatal, message, __MODULE__, Class()->GetName(), __FUNCTION__, __FILE__, __LINE__);}
-#define AliFatalGeneral(scope, message) {AliLog::Message(AliLog::kFatal, message, __MODULE__, scope, __FUNCTION__, __FILE__, __LINE__);}
+// fatal messages
+#define AliFatal(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), ClassName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliFatalClass(message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), Class()->GetName(), FUNCTIONNAME(), __FILE__, __LINE__);}
+#define AliFatalGeneral(scope, message) {AliLog::Message(AliLog::kFatal, message, MODULENAME(), scope, FUNCTIONNAME(), __FILE__, __LINE__);}
 
 #endif