FastLogger.cpp

Go to the documentation of this file.
00001 /*
00002 Copyright 2007, 2008, 2009, 2010, 2011 Instituto de Sistemas e Robotica, Instituto Superior Tecnico
00003 
00004 This file is part of MeRMaID.
00005 
00006 MeRMaID is free software: you can redistribute it and/or modify
00007 it under the terms of the GNU Lesser General Public License as published by
00008 the Free Software Foundation, either version 3 of the License, or
00009 (at your option) any later version.
00010 
00011 MeRMaID is distributed in the hope that it will be useful,
00012 but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 GNU Lesser General Public License for more details.
00015 
00016 You should have received a copy of the GNU Lesser General Public License
00017 along with MeRMaID.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 
00021 
00022 /**
00023  * @Filename FastLogger.cpp
00024  * @Description FastLogger implementation
00025  * @Status Finished
00026  * @Version $Id: FastLogger.cpp 1 2011-03-04 18:13:18Z jreis $
00027  * @Maintainer Joao Reis (joaocgreis@gmail.com)
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   // Indentation is calculated so that 0 is valid for all levels.
00132   // LOG_BEGIN with indentation 0 means we are going from 0 to 1
00133   // LOG_END with indentation 0 means we are going from 1 to 0
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   // time from the instantiation of the first logger
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 << " ("; // time from the last begin
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 }
Generated on Fri Mar 4 22:14:58 2011 for MeRMaID::support by  doxygen 1.6.3