Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

Logger.h

Go to the documentation of this file.
00001 #ifndef Impala_Basis_Logger_h
00002 #define Impala_Basis_Logger_h
00003 
00004 /*********************************************************************
00005  * Class: Logger
00006  *
00007  * Base logging class for registering user actions and debug messages
00008  *
00009  * Primary Author: Ork, orooij, 04-09-2006
00010  ********************************************************************/
00011 
00012 #include "Basis/Timer.h"
00013 //#include "Link/OGL/UndefLinkListMacros.h"
00014 #include <map>
00015 #include <iostream>
00016 #include <sstream>
00017 #include <fstream>
00018 
00019 
00020 namespace Impala
00021 {
00022 
00023 
00024 class LogListener
00025 {
00026 public:
00027     virtual void
00028     LogString(String, bool isPartial, int level) = 0;
00029 
00030     virtual void
00031     EndLine(int level) = 0;
00032 };
00033 
00034 
00035 class LogType
00036 {
00037 public:
00038     LogType(int level, LogListener *target) 
00039     {
00040         mLevel  = level;
00041         mLogger = target;
00042     }
00043 
00044     LogType&
00045     operator<<(String log)
00046     {
00047         mLogger->LogString(log, true, mLevel);
00048         return *this;
00049     }
00050 
00051     template <class T>
00052     LogType&
00053     operator<<(T log)
00054     {
00055         std::ostringstream s;
00056         s << log;
00057         mLogger->LogString(s.str(), true, mLevel);
00058         return *this;
00059     }
00060 
00061     LogType&
00062     operator<<( std::ostream& (*f)(std::ostream&) )
00063     {
00064         mLogger->EndLine(mLevel);
00065         return *this;
00066     }
00067 
00068 private:
00069     int mLevel;
00070     LogListener *mLogger;
00071 };
00072 
00073 
00074 class Logger : public LogListener
00075 {
00076 public:
00077 
00078     static void
00079     Configure(int logLevel, String logFile, bool debug)
00080     {
00081         GetInstance().Init(logLevel, logFile, debug);
00082     }
00083 
00084     static LogType
00085     Debug(int level=Logger::LOG_DEBUG)
00086     {
00087         return Log(level);
00088     }
00089 
00090     static LogType
00091     Log(int level=Logger::LOG_INFO)
00092     {
00093         return LogType(level, &Logger::GetInstance());
00094     }
00095 
00096     static LogType
00097     User()
00098     {
00099         return Log(Logger::LOG_USER);
00100     }
00101 
00102     static LogType
00103     System()
00104     {
00105         return Log(Logger::LOG_SYSTEM);
00106     }
00107 
00108     static LogType
00109     Error()
00110     {
00111         return Log(Logger::LOG_ERROR);
00112     }
00113 
00114     static LogType
00115     Warning()
00116     {
00117         return Log(Logger::LOG_WARNING);
00118     }
00119 
00120     static LogType
00121     Information()
00122     {
00123         return Log(Logger::LOG_INFO);
00124     }
00125 
00126     virtual
00127     ~Logger()
00128     {
00129         LogString("Logger destructed.");
00130         if (mLogToFile)
00131             mLog->close();
00132         mErrorLog->close();
00133     }
00134 
00135     static const int LOG_DEBUG   = 1;
00136     static const int LOG_INFO    = 2;
00137     static const int LOG_WARNING = 3;
00138     static const int LOG_ERROR   = 4;
00139     static const int LOG_ACTION  = 5;
00140     static const int LOG_SYSTEM  = 6;
00141     static const int LOG_USER    = 7;
00142 
00143     static void
00144     StartAction(String actionName, int level=LOG_USER)
00145     {
00146         Logger *al = &GetInstance();
00147         al->mActionTimes[actionName] = al->mTimer->SplitTime();
00148         al->mActionLevels[actionName] = level;
00149         std::ostringstream s;
00150         s << "ACTION START: " << actionName;
00151         al->LogString(s.str(), false, level);
00152     }
00153 
00154     static double
00155     EndAction(String actionName)
00156     {
00157         Logger *al = &GetInstance();
00158         if (al->mActionTimes.find(actionName) == al->mActionTimes.end())
00159         {
00160             Warning() << "EndAction called but no action started: "
00161                       << actionName << std::endl;
00162             return 0.0;
00163         }
00164 
00165         double delta = al->mTimer->SplitTime() - al->mActionTimes[actionName];
00166         std::ostringstream s;
00167         s << "ACTION STOP: " << actionName << ", " << delta << " seconds";
00168         al->LogString(s.str(), false, al->mActionLevels[actionName]);
00169         return delta;
00170     }
00171 
00172     static void
00173     OpenPartLog()
00174     {
00175         Logger *al = &GetInstance();
00176         al->DoOpenPartLog();
00177     }
00178 
00179     static void
00180     ClosePartLog(String filename)
00181     {
00182         Logger *al = &GetInstance();
00183         al->DoClosePartLog(filename);
00184     }
00185 
00186 
00187 protected:
00188 
00189     virtual void
00190     LogString(String log, bool isPartial=false, int level=LOG_DEBUG)
00191     {
00192         if (level < mShowLevel)
00193             return;
00194 
00195         if (!mLineStarted)
00196         {
00197             std::cout << mTimer->SplitTimeStr() << " " << GetHeader(level)
00198                       << ": ";
00199             if (mLogToFile)
00200                 *mLog << mTimer->SplitTime() <<  " " << GetHeader(level) << ": ";
00201             if (mPLog != 0)
00202                 *mPLog << mTimer->SplitTime() <<  " " << GetHeader(level) << ": ";
00203             if (level == LOG_ERROR)
00204                 *mErrorLog << mTimer->SplitTime() <<  " " << GetHeader(level)
00205                            << ": ";
00206         }
00207 
00208         std::cout << log;
00209 
00210         if (mLogToFile)
00211             *mLog << log;
00212         if (mPLog != 0)
00213             *mPLog << log;
00214         if (level == LOG_ERROR)
00215             *mErrorLog << log;
00216 
00217         mLineStarted = true;
00218         if (!isPartial)
00219             EndLine(level);
00220     }
00221 
00222     void
00223     EndLine(int level)
00224     {
00225         if (mLineStarted)
00226         {
00227             std::cout << std::endl;
00228             if (mLogToFile)
00229                 *mLog << std::endl;
00230             if (mPLog != 0)
00231                 *mPLog << std::endl;
00232             if (level == LOG_ERROR)
00233                 *mErrorLog << std::endl;
00234 
00235             mLineStarted = false;
00236         }
00237     }
00238 
00239     String
00240     GetHeader(int level)
00241     {
00242         switch (level)
00243         {
00244             case LOG_DEBUG:  return "DEBUG   ";
00245             case LOG_INFO:   return "INFO    ";
00246             case LOG_WARNING:return "WARNING ";
00247             case LOG_ERROR:  return "ERROR   ";
00248             case LOG_ACTION: return "ACTION  ";
00249             case LOG_SYSTEM: return "SYSTEM  ";
00250             case LOG_USER:   return "USER    ";
00251         }
00252         return "??      ";
00253     }
00254 
00255     void
00256     DoOpenPartLog()
00257     {
00258         if (mPLog != 0)
00259         {
00260             LogString("DoOpenPartLog: closing last part log.");
00261             delete mPLog;
00262         }
00263         mPLog = new std::ostringstream();
00264         LogString("Partial log started.");
00265     }
00266 
00267     void
00268     DoClosePartLog(String filename)
00269     {
00270         std::ostringstream s;
00271         s << "Writing partial log to file " << filename;
00272         LogString(s.str());
00273         std::fstream f(filename.c_str(), std::ios::out);
00274         f << mPLog->str();
00275         f << std::endl;
00276         f.close();
00277         delete mPLog;
00278         mPLog = 0;
00279     }
00280 
00281 public:
00282 
00283     Logger&
00284     operator<<(String log)
00285     {
00286         LogString(log, true, LOG_DEBUG);
00287         return *this;
00288     }
00289 
00290     Logger&
00291     operator<<( std::ostream& (*f)(std::ostream&) )
00292     {
00293         EndLine(mShowLevel);
00294         return *this;
00295     }
00296 
00297 
00298 private:
00299 
00300     static Logger&
00301     GetInstance()
00302     {
00303         static Logger theLogger;
00304         return theLogger;
00305     }
00306 
00307     Logger()
00308     {
00309     }
00310 
00311     void
00312     Init(int logLevel, String logFile, bool debug)
00313     {
00314         mLineStarted = false;
00315         mTimer = new Timer(1);
00316 //        mActionTimer = new Timer(1);
00317         mShowLevel = logLevel;
00318         mLogFile = logFile;
00319         mLogToFile = !mLogFile.empty();
00320         if (debug)
00321             mShowLevel = LOG_DEBUG;
00322 
00323         std::ostringstream s;
00324         s << "Logger started @ level " << mShowLevel;
00325 
00326         if (mLogToFile)
00327         {
00328             mLog = new std::fstream(mLogFile.c_str(),
00329                                     std::ios::out | std::ios::app);
00330         }
00331         else
00332         {
00333             mLog = 0;
00334         }
00335         mPLog = 0;
00336         mErrorLog = new std::fstream("errors.log", std::ios::out | std::ios::app);
00337         LogString(s.str());
00338     }
00339 
00340     std::map<String, double> mActionTimes;
00341     std::map<String, int> mActionLevels;
00342     String mLogFile;
00343     bool mLogToFile;
00344     bool mLineStarted;
00345     int mShowLevel;
00346     Timer *mTimer;
00347     std::fstream *mLog;
00348     std::ostringstream *mPLog;
00349     std::fstream *mErrorLog;
00350 
00351 };
00352 
00353 } // namespace Impala
00354 
00355 #endif

Generated on Fri Mar 19 09:30:42 2010 for ImpalaSrc by  doxygen 1.5.1