FastLogger.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "config.h"
00031
00032 #include <ctime>
00033
00034 #include "Logger.hpp"
00035
00036 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00037 #include <sys/time.h>
00038 #include <time.h>
00039 bool hasTime_ = false;
00040 struct timeval firstTime_;
00041 #endif //MERMAID_LOGGER_QUICK_PROFILING
00042
00043
00044
00045 using namespace mermaid::support::logging;
00046
00047
00048
00049 shared_ptr<Logger> FastLogger::build()
00050 {
00051 return shared_ptr<Logger> (new FastLogger());
00052 }
00053
00054
00055
00056 shared_ptr<Logger> FastLogger::build (const std::string& prefix)
00057 {
00058 return shared_ptr<Logger> (new FastLogger (prefix));
00059 }
00060
00061
00062
00063 FastLogger::FastLogger() :
00064 indentation_ (0),
00065 prefix_(),
00066 levelOutputs_ (std::map<LogLevel, std::list<shared_ptr<LogOutput> > >())
00067 {
00068 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00069 struct timeval time;
00070 gettimeofday (&time, NULL);
00071 if (!hasTime_) {
00072 firstTime_ = time;
00073 hasTime_ = true;
00074 }
00075 beginTimes_.push (time);
00076 #endif //MERMAID_LOGGER_QUICK_PROFILING
00077 }
00078
00079
00080
00081 FastLogger::FastLogger (const std::string& prefix) :
00082 indentation_ (0),
00083 prefix_ (prefix),
00084 levelOutputs_ (std::map<LogLevel, std::list<shared_ptr<LogOutput> > >())
00085 {
00086 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00087 struct timeval time;
00088 gettimeofday (&time, NULL);
00089 if (!hasTime_) {
00090 firstTime_ = time;
00091 hasTime_ = true;
00092 }
00093 beginTimes_.push (time);
00094 #endif //MERMAID_LOGGER_QUICK_PROFILING
00095 }
00096
00097
00098
00099 void FastLogger::enableLogLevel (const LogLevel& logLevel,
00100 shared_ptr<LogOutput> logOutput)
00101 {
00102 levelOutputs_[logLevel].push_back (logOutput);
00103 }
00104
00105
00106
00107 void FastLogger::disableLogLevel (const LogLevel& logLevel,
00108 shared_ptr<LogOutput> logOutput)
00109 {
00110 levelOutputs_[logLevel].remove (logOutput);
00111 }
00112
00113
00114
00115 void FastLogger::disableLogLevel (const LogLevel& logLevel)
00116 {
00117 levelOutputs_[logLevel].clear();
00118 }
00119
00120
00121
00122 void FastLogger::setPrefix (const std::string& prefix)
00123 {
00124 prefix_ = prefix;
00125 }
00126
00127
00128
00129 int FastLogger::updateIndentation_ (const LogLevel& logLevel)
00130 {
00131
00132
00133
00134 int ret;
00135 if ( (logLevel == LOG_END) && (indentation_ > 0)) {
00136 indentation_--;
00137 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00138 beginTimes_.pop();
00139 #endif //MERMAID_LOGGER_QUICK_PROFILING
00140 }
00141 ret = indentation_;
00142 if (logLevel == LOG_BEGIN) {
00143 indentation_++;
00144 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00145 struct timeval time;
00146 gettimeofday (&time, NULL);
00147 beginTimes_.push (time);
00148 #endif //MERMAID_LOGGER_QUICK_PROFILING
00149 }
00150 return ret;
00151 }
00152
00153
00154
00155 void FastLogger::log (const LogLevel& logLevel,
00156 const std::string& message)
00157 {
00158 time_t t = time (NULL);
00159 int indentation = updateIndentation_ (logLevel);
00160
00161 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00162 struct timeval time;
00163 gettimeofday (&time, NULL);
00164 unsigned long long sec, usec;
00165
00166 std::stringstream p;
00167
00168 if (time.tv_usec >= firstTime_.tv_usec) {
00169 sec = time.tv_sec - firstTime_.tv_sec;
00170 usec = time.tv_usec - firstTime_.tv_usec;
00171 }
00172 else {
00173 sec = time.tv_sec - firstTime_.tv_sec - 1;
00174 usec = ( (unsigned long long) 1000000) + time.tv_usec
00175 - firstTime_.tv_usec;
00176 }
00177 p.width (0);
00178 p << sec << ".";
00179 p.fill ('0');
00180 p.width (6);
00181 p << usec << " ";
00182 p << prefix_;
00183 std::string thePrefix = prefix_;
00184 prefix_ = p.str();
00185
00186 if ( (logLevel == LOG_END)
00187 || (logLevel == LOG_STEP)
00188 || (logLevel == LOG_SEPARATOR)) {
00189 std::stringstream s;
00190 s << message;
00191 s << " (";
00192 if (time.tv_usec >= beginTimes_.top().tv_usec) {
00193 sec = time.tv_sec - beginTimes_.top().tv_sec;
00194 usec = time.tv_usec - beginTimes_.top().tv_usec;
00195 }
00196 else {
00197 sec = time.tv_sec - beginTimes_.top().tv_sec - 1;
00198 usec = ( (unsigned long long) 1000000) + time.tv_usec
00199 - beginTimes_.top().tv_usec;
00200 }
00201 s.width (0);
00202 s << sec << ".";
00203 s.fill ('0');
00204 s.width (6);
00205 s << usec << "s)";
00206 message = s.str();
00207 }
00208
00209 if ( (logLevel == LOG_END) && (beginTimes_.size() > 1)) {
00210 beginTimes_.pop();
00211 }
00212 if (logLevel == LOG_BEGIN) {
00213 struct timeval time;
00214 gettimeofday (&time, NULL);
00215 beginTimes_.push (time);
00216 }
00217 #endif //MERMAID_LOGGER_QUICK_PROFILING
00218
00219 std::list<shared_ptr<LogOutput> >& logList = levelOutputs_[logLevel];
00220 for (std::list<shared_ptr<LogOutput> >::iterator i = logList.begin();
00221 i != logList.end();
00222 i++) {
00223 (*i)->outputMessage (LogMessage (logLevel,
00224 t,
00225 indentation,
00226 prefix_,
00227 message));
00228 }
00229
00230 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00231 prefix_ = thePrefix;
00232 #endif //MERMAID_LOGGER_QUICK_PROFILING
00233 }