Go to the documentation of this file.00001
00009 #pragma once
00010
00011 #ifdef WIN32
00012 #include <win32_compat.h>
00013 #endif
00014
00015 #include <iostream>
00016 #include <sstream>
00017 #include <fstream>
00018 #include <streambuf>
00019 #include <iomanip>
00020
00021 #define LOG_MAX_CUSTOMLOGS 10 // Number of custom logs available, besides cout and cerr
00022
00023 #ifdef _WIN32
00024 # include <windows.h>
00025 # define FOREGROUND_BROWN (FOREGROUND_RED|FOREGROUND_GREEN)
00026 # define FOREGROUND_MAGENTA (FOREGROUND_RED|FOREGROUND_BLUE)
00027 # define FOREGROUND_CYAN (FOREGROUND_BLUE|FOREGROUND_GREEN)
00028 # define FOREGROUND_GRAY (FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN)
00029 # define CONSL_UNDERSCORE COMMON_LVB_UNDERSCORE
00030 # define CONSL_INTENSITY FOREGROUND_INTENSITY
00031 #else
00032 # define FOREGROUND_RED 31
00033 # define FOREGROUND_GREEN 32
00034 # define FOREGROUND_BLUE 34
00035 # define FOREGROUND_BROWN 33
00036 # define FOREGROUND_MAGENTA 35
00037 # define FOREGROUND_CYAN 36
00038 # define FOREGROUND_GRAY 37
00039 # define CONSL_UNDERSCORE 4
00040 # define CONSL_INTENSITY 1
00041
00042 #endif
00043
00044 using std::endl;
00045 using std::ends;
00046 using std::flush;
00047
00048 enum ELogLevel {llCrawl, llDebug, llInfo, llNotice, llWarning, llError, llCritical, llClean};
00049
00050 class CLockable
00051 {
00052 friend class CCriticalSection;
00053
00054 private:
00055 pthread_mutex_t mMutex;
00056
00057 protected:
00058 void lock(void)
00059 {
00060 pthread_mutex_lock(&mMutex);
00061 }
00062
00063 void unlock(void)
00064 {
00065 pthread_mutex_unlock(&mMutex);
00066 }
00067
00068 public:
00069 CLockable()
00070 {
00071 pthread_mutex_init(&mMutex, NULL);
00072 }
00073 };
00074
00075 class CCriticalSection
00076 {
00077 private:
00078 CLockable &mObj;
00079
00080 public:
00081 CCriticalSection(CLockable &obj) : mObj(obj)
00082 {
00083 mObj.lock();
00084 }
00085
00086 ~CCriticalSection()
00087 {
00088 mObj.unlock();
00089 }
00090 };
00091
00092 class CLogStream: public std::ostream, public CLockable
00093 {
00094 private:
00095 ELogLevel mLevel;
00096
00097 public:
00098 CLogStream(std::stringbuf* buffer): std::ostream(buffer) {}
00099 void setLevel(ELogLevel level) { mLevel = level; }
00100 inline ELogLevel getLevel() const { return mLevel; }
00101 virtual void setSystemHeader(const std::string &text) { }
00102
00103 virtual void enableConsoleOutput(bool bEnabled) {}
00104 virtual void redirectConsoleOutput(FILE* file) {}
00105
00106 virtual FILE* enableFileOutput(bool bEnabled, const std::string& filename="") { return NULL;}
00107 virtual void flushFileOutput() {}
00108 virtual void enableTimeStamping(bool enabled) {}
00109 virtual void setHeaderText(const std::string &HeaderText)=0;
00110 virtual std::string& headerText()=0;
00111 virtual void setHeaderColor(int HeaderColor) {}
00112 virtual void setMessageColor(int MessageColor) {}
00113 };
00114
00115 class CLog
00116 {
00117 protected:
00118 int mNumCustomLogStreams;
00119 std::string mCustomLogStreamNames[LOG_MAX_CUSTOMLOGS];
00120
00121 public:
00122 CLog(): mNumCustomLogStreams(0) {}
00123 virtual ~CLog() {}
00124 virtual CLogStream& cout()=0;
00125 virtual CLogStream& cerr()=0;
00126 virtual CLogStream& ccustom(const int index)=0;
00127
00128
00129
00130 int getCustomLogIndex(const std::string& customLogName)
00131 {
00132 for (int i=0; i<mNumCustomLogStreams; i++)
00133 if (mCustomLogStreamNames[i] == customLogName)
00134 return i;
00135
00136
00137 if (mNumCustomLogStreams < LOG_MAX_CUSTOMLOGS)
00138 {
00139 mCustomLogStreamNames[mNumCustomLogStreams] = customLogName;
00140 mNumCustomLogStreams++;
00141 return mNumCustomLogStreams-1;
00142 }
00143 else
00144 {
00145
00146 cerr() << "[ERROR] Cannot create custom log named \"" << customLogName << "\": maximum reached (" << LOG_MAX_CUSTOMLOGS << ")! Returning \"" << mCustomLogStreamNames[LOG_MAX_CUSTOMLOGS-1] << "\" instead." << endl;
00147 return LOG_MAX_CUSTOMLOGS-1;
00148 }
00149 }
00150 };
00151
00152