Logger.hpp

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 Logger.hpp
00024  * @Description Logger declaration
00025  * @Status Finished
00026  * @Version $Id: Logger.hpp 1 2011-03-04 18:13:18Z jreis $
00027  * @Maintainer Joao Reis (joaocgreis@gmail.com)
00028  */
00029 
00030 #ifndef LOGGER_HPP
00031 #define LOGGER_HPP
00032 
00033 
00034 
00035 /**
00036  * Enables a prototype for quick profiling of code, based on the logger.
00037  * This was just an experiment, but it's already done so I'll let it be.
00038  */
00039 #undef MERMAID_LOGGER_QUICK_PROFILING
00040 
00041 // Compile time Logger configurations
00042 /**
00043  * Disables the shortcuts to the reporting levels, for speed purposes.
00044  * Please mind that this will not affect any of the methods called log.
00045  */
00046 #undef MERMAID_LOGGER_DISABLE_REPORTING
00047 // If we really need it, we could create another class, DummyLogger,
00048 // that completely implemented the logger with empty methods.
00049 // Then we would only need to change the lines where the logger is crated.
00050 
00051 
00052 
00053 #include <ctime>
00054 #include <fstream>
00055 #include <list>
00056 #include <map>
00057 #include <set>
00058 #include <sstream>
00059 #include <stack>
00060 #include <string>
00061 
00062 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00063 #include <sys/time.h>
00064 #include <time.h>
00065 #endif //MERMAID_LOGGER_QUICK_PROFILING
00066 
00067 #include "ace/Synch.h"
00068 
00069 #include <boost/foreach.hpp>
00070 #define foreach BOOST_FOREACH
00071 
00072 
00073 #include <DataBox.hpp>
00074 
00075 
00076 
00077 /**
00078  * Logs an ERROR using a <code>std::ostringstream</code>.
00079  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00080  * <code>message</code> into it and calls the method <code>error</code>
00081  * from the logger you specified.
00082  * @see mermaid::support::logging::Logger.error()
00083  * @param logger The logger to use. Must evaluate to an instance of
00084  * <code>mermaid::support::logging::Logger</code>
00085  * @param message Somethog to be inserted into the
00086  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00087  */
00088 #define LERROR(logger, message) {std::ostringstream tmp; tmp << message; (logger)->error(tmp.str());}
00089 /**
00090  * Logs a WARN using a <code>std::ostringstream</code>.
00091  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00092  * <code>message</code> into it and calls the method <code>warn</code>
00093  * from the logger you specified.
00094  * @see mermaid::support::logging::Logger.warn()
00095  * @param logger The logger to use. Must evaluate to an instance of
00096  * <code>mermaid::support::logging::Logger</code>
00097  * @param message Somethog to be inserted into the
00098  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00099  */
00100 #define LWARN(logger, message) {std::ostringstream tmp; tmp << message; (logger)->warn(tmp.str());}
00101 /**
00102  * Logs an INFO using a <code>std::ostringstream</code>.
00103  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00104  * <code>message</code> into it and calls the method <code>info</code>
00105  * from the logger you specified.
00106  * @see mermaid::support::logging::Logger.info()
00107  * @param logger The logger to use. Must evaluate to an instance of
00108  * <code>mermaid::support::logging::Logger</code>
00109  * @param message Somethog to be inserted into the
00110  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00111  */
00112 #define LINFO(logger, message) {std::ostringstream tmp; tmp << message; (logger)->info(tmp.str());}
00113 
00114 #ifndef MERMAID_LOGGER_DISABLE_REPORTING
00115 /**
00116  * Logs a BEGIN using a <code>std::ostringstream</code>.
00117  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00118  * <code>message</code> into it and calls the method <code>begin</code>
00119  * from the logger you specified.
00120  * @see mermaid::support::logging::Logger.begin()
00121  * @param logger The logger to use. Must evaluate to an instance of
00122  * <code>mermaid::support::logging::Logger</code>
00123  * @param message Somethog to be inserted into the
00124  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00125  */
00126 #define LBEGIN(logger, message) {std::ostringstream tmp; tmp << message; (logger)->begin(tmp.str());}
00127 /**
00128  * Logs a SEPARATOR using a <code>std::ostringstream</code>.
00129  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00130  * <code>message</code> into it and calls the method <code>separator</code>
00131  * from the logger you specified.
00132  * @see mermaid::support::logging::Logger.separator()
00133  * @param logger The logger to use. Must evaluate to an instance of
00134  * <code>mermaid::support::logging::Logger</code>
00135  * @param message Somethog to be inserted into the
00136  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00137  */
00138 #define LSEPARATOR(logger, message) {std::ostringstream tmp; tmp << message; (logger)->separator(tmp.str());}
00139 /**
00140  * Logs a STEP using a <code>std::ostringstream</code>.
00141  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00142  * <code>message</code> into it and calls the method <code>step</code>
00143  * from the logger you specified.
00144  * @see mermaid::support::logging::Logger.step()
00145  * @param logger The logger to use. Must evaluate to an instance of
00146  * <code>mermaid::support::logging::Logger</code>
00147  * @param message Somethog to be inserted into the
00148  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00149  */
00150 #define LSTEP(logger, message) {std::ostringstream tmp; tmp << message; (logger)->step(tmp.str());}
00151 /**
00152  * Logs an END using a <code>std::ostringstream</code>.
00153  * This macro crates a temporary <code>std::ostringstream</code>, inserts
00154  * <code>message</code> into it and calls the method <code>end</code>
00155  * from the logger you specified.
00156  * @see mermaid::support::logging::Logger.end()
00157  * @param logger The logger to use. Must evaluate to an instance of
00158  * <code>mermaid::support::logging::Logger</code>
00159  * @param message Somethog to be inserted into the
00160  * <code>std::ostringstream</code>. May contain more <code><<</code> operators.
00161  */
00162 #define LEND(logger, message) {std::ostringstream tmp; tmp << message; (logger)->end(tmp.str());}
00163 #else
00164 /** Disabled by MERMAID_LOGGER_DISABLE_REPORTING in compile time */
00165 #define LBEGIN(logger, message) {}
00166 /** Disabled by MERMAID_LOGGER_DISABLE_REPORTING in compile time */
00167 #define LSEPARATOR(logger, message) {}
00168 /** Disabled by MERMAID_LOGGER_DISABLE_REPORTING in compile time */
00169 #define LSTEP(logger, message) {}
00170 /** Disabled by MERMAID_LOGGER_DISABLE_REPORTING in compile time */
00171 #define LEND(logger, message) {}
00172 #endif // MERMAID_LOGGER_DISABLE_REPORTING
00173 
00174 
00175 
00176 namespace mermaid
00177 {
00178   namespace support
00179   {
00180     /// Namespace for the Logging Framework.
00181     namespace logging
00182     {
00183       using boost::shared_ptr;
00184       
00185       /**
00186        * @enum LogLevel
00187        * @Description The LogLevel enum lists all the logger levels.
00188        * @Author Joao Reis
00189        */
00190       enum LogLevel {
00191         // Error levels
00192         LOG_ERROR, /**< Error level (Error levels group) */
00193         LOG_WARN, /**< Warn level (Error levels group) */
00194         LOG_INFO, /**< Info level (Error levels group) */
00195         // Reporting levels
00196         LOG_BEGIN, /**< Begin level (Reporting levels group) */
00197         LOG_STEP, /**< Step level (Reporting levels group) */
00198         LOG_SEPARATOR, /**< Separator level (Reporting levels group) */
00199         LOG_END /**< End level (Reporting levels group) */
00200       };
00201       
00202       
00203       
00204       /**
00205        * @Class LogMessage
00206        * @Description This class represents a message of the logger.
00207        *
00208        * The LogMessage is sent by the Logger class to the LogOutput(s).
00209        * @Author Joao Reis
00210        */
00211       class LogMessage
00212       {
00213         public:
00214           /**
00215           * @Description Creates a new LogMessage.
00216           * @Argument logLevel The level of the message.
00217           * @Argument time The time when the message was issued.
00218           * @Argument indentation Indentation level of the message for
00219           * reporting levels.
00220           * @Argument prefix The logger prefix when the message was issued.
00221           * @Argument message The message to log.
00222           * @Author Joao Reis
00223           */
00224           LogMessage (const LogLevel& logLevel,
00225                       const time_t& time,
00226                       const int& indentation,
00227                       const std::string& prefix,
00228                       const std::string& message) :
00229               logLevel_ (logLevel),
00230               time_ (time),
00231               indentation_ (indentation),
00232               prefix_ (prefix),
00233               message_ (message) {
00234           }
00235           /**
00236           * @Description Gets the LogLevel of the message.
00237           * @Returns The LogLevel of the message.
00238           * @Author Joao Reis
00239           */
00240           inline const LogLevel& getLogLevel() const {
00241             return logLevel_;
00242           }
00243           /**
00244           * @Description Gets the time when the message was issued.
00245           * @Returns The time when the message was issued.
00246           * @Author Joao Reis
00247           */
00248           inline const time_t& getTime() const {
00249             return time_;
00250           }
00251           /**
00252           * @Description Gets the indentation of the message.
00253           * @Returns The indentation of the message.
00254           * @Author Joao Reis
00255           */
00256           inline const int& getIndentation() const {
00257             return indentation_;
00258           }
00259           /**
00260           * @Description Gets the prefix of the logger when the message was issued.
00261           * @Returns The prefix of the logger.
00262           * @Author Joao Reis
00263           */
00264           inline const std::string& getPrefix() const {
00265             return prefix_;
00266           }
00267           /**
00268           * @Description Gets the message.
00269           * @Returns The actual message.
00270           * @Author Joao Reis
00271           */
00272           inline const std::string& getMessage() const {
00273             return message_;
00274           }
00275           
00276         private:
00277           LogLevel logLevel_;
00278           time_t time_;
00279           int indentation_;
00280           std::string prefix_;
00281           std::string message_;
00282       };
00283       
00284       
00285       
00286       /**
00287        * @Class LogOutput
00288        * @Description LogOutput is something that handles the Logger output.
00289        *
00290        * LogOutput is an abstract class, where all the LogMessage's
00291        * generated by the Logger go.
00292        * @Author Joao Reis
00293        */
00294       class LogOutput
00295       {
00296         public:
00297           /**
00298            * @Description Logs a message generated by the logger.
00299            * @Argument logMessage the message to log.
00300            * @Author Joao Reis
00301            */
00302           virtual void outputMessage (const LogMessage& logMessage) = 0;
00303           virtual ~LogOutput() {}
00304       };
00305       
00306       
00307       
00308       /**
00309        * @Class Logger
00310        * @Description Main class of the logger framework.
00311        * @Author Joao Reis
00312        */
00313       class Logger
00314       {
00315         public:
00316           // Knowledge about the levels should be all contained in the
00317           // LogLevels enum, but the logger also knows about them.
00318           // To minimize the number of classes that know about the
00319           // levels, only methods that don't depend on them are maked
00320           // virtual. Shortcuts should stay in this base class.
00321           
00322           /**
00323            * @Description Sets the prefix of the Logger.
00324            *
00325            * Each Logger can have exactly one prefix that is printed
00326            * before every message.
00327            * @Argument prefix The prefix to use.
00328            * @Author Joao Reis
00329            */
00330           virtual void setPrefix (const std::string& prefix) = 0;
00331           
00332           
00333           
00334           /**
00335            * @Description Enables a specific output for a specific log level.
00336            * @Argument logLevel The logLevel to associate.
00337            * @Argument logOutput The logOutput to associate with the logLevel.
00338            * @Author Joao Reis
00339            */
00340           virtual void enableLogLevel (const LogLevel& logLevel,
00341                                        shared_ptr<LogOutput> logOutput) = 0;
00342           /**
00343            * @Description Enables the error levels (LOG_ERROR, LOG_WARN and LOG_INFO) for the given output.
00344            * @Argument logOutput Will enable the levels for this logOutput.
00345            * @Author Joao Reis
00346            */
00347           void enableErrorLogLevels (shared_ptr<LogOutput> logOutput);
00348           /**
00349            * @Description Enables the reporting levels (LOG_BEGIN, LOG_END, LOG_STEP and LOG_SEPARATOR) for the given output.
00350            * @Argument logOutput Will enable the levels for this logOutput.
00351            * @Author Joao Reis
00352            */
00353           void enableReportingLogLevels (shared_ptr<LogOutput> logOutput);
00354           /**
00355            * @Description Enables all levels for the given output.
00356            * @Argument logOutput Will enable the levels for this logOutput.
00357            * @Author Joao Reis
00358            */
00359           void enableAllLogLevels (shared_ptr<LogOutput> logOutput);
00360           /**
00361            * @Description Disables a specified output for a specific level.
00362            * @Argument logLevel The logOutput will be disabled only for this level.
00363            * @Argument logOutput The logOutput to disble for the logLevel.
00364            * @Author Joao Reis
00365            */
00366           virtual void disableLogLevel (const LogLevel& logLevel,
00367                                         shared_ptr<LogOutput> logOutput) = 0;
00368           /**
00369            * @Description Disables all outputs for the specified logLevel.
00370            * @Argument logLevel All the outputs of this level will be disabled.
00371            * @Author Joao Reis
00372            */
00373           virtual void disableLogLevel (const LogLevel& logLevel) = 0;
00374           /**
00375            * @Description Disables all levels for the given output.
00376            * @Argument logOutput Will disable the levels for this logOutput.
00377            * @Author Joao Reis
00378            */
00379           void disableAllLogLevels (shared_ptr<LogOutput> logOutput);
00380           /**
00381            * @Description Disables all outputs for all the levels, completely stopping the Logger.
00382            *
00383            * This method will stop the logger if you need it. It is
00384            * necessary because you cannot delete the logger, it is always a shared_ptr.
00385            * @Author Joao Reis
00386            */
00387           void disableAllLogLevels();
00388           
00389           
00390           
00391           /**
00392            * @Description Logs a message, given in the form of a string.
00393            *
00394            * This is the main method of the logger, all the others
00395            * just call this one internally.
00396            *
00397            * Please mind that this method is not affected by MERMAID_LOGGER_DISABLE_REPORTING.
00398            * @Argument logLevel The log level to use.
00399            * @Argument message The message to log.
00400            * @Author Joao Reis
00401            */
00402           virtual void log (const LogLevel& logLevel,
00403                             const std::string& message) = 0;
00404           /**
00405            * @Description Logs a DataBox.
00406            *
00407            * Please mind that this method is not affected by MERMAID_LOGGER_DISABLE_REPORTING.
00408            * @Argument logLevel The log level to use.
00409            * @Argument message The message to log.
00410            * @Author Joao Reis
00411            */
00412           void log (const LogLevel& logLevel,
00413                     const mermaid::support::data::DataBox& message);
00414                     
00415                     
00416                     
00417           /**
00418           * @Description Logs a string with the level LOG_ERROR.
00419           * @Argument message The message to log.
00420           * @Author Joao Reis
00421           */
00422           void error (const std::string& message);
00423           /**
00424           * @Description Logs a string with the level LOG_WARN.
00425           * @Argument message The message to log.
00426           * @Author Joao Reis
00427           */
00428           void warn (const std::string& message);
00429           /**
00430           * @Description Logs a string with the level LOG_INFO.
00431           * @Argument message The message to log.
00432           * @Author Joao Reis
00433           */
00434           void info (const std::string& message);
00435           /**
00436           * @Description Logs a string with the level LOG_BEGIN.
00437           * @Argument message The message to log.
00438           * @Author Joao Reis
00439           */
00440           void begin (const std::string& message = "");
00441           /**
00442           * @Description Logs a string with the level LOG_SEPARATOR.
00443           * @Argument message The message to log.
00444           * @Author Joao Reis
00445           */
00446           void separator (const std::string& message = "");
00447           /**
00448           * @Description Logs a string with the level LOG_STEP.
00449           * @Argument message The message to log.
00450           * @Author Joao Reis
00451           */
00452           void step (const std::string& message);
00453           /**
00454           * @Description Logs a string with the level LOG_END.
00455           * @Argument message The message to log.
00456           * @Author Joao Reis
00457           */
00458           void end (const std::string& message = "");
00459           
00460           
00461           
00462         protected:
00463           Logger() {};
00464           // virtual ~Logger() {};
00465           // needed by effc++, hated by shared_ptr
00466       };
00467       
00468       
00469       
00470       /**
00471       * @Class ThreadSafeLogger
00472       * @Description Thread safe implementation of the logger.
00473       * @Author Joao Reis
00474       */
00475       class ThreadSafeLogger : public Logger
00476       {
00477         public:
00478           /**
00479           * @Description Creates a new ThreadSafeLogger with an empty prefix.
00480           * @Returns A shared_ptr to the new Logger.
00481           * @Author Joao Reis
00482           */
00483           static shared_ptr<Logger> build();
00484           /**
00485           * @Description Creates a new ThreadSafeLogger with the given prefix.
00486           * @Returns A shared_ptr to the new Logger.
00487           * @Argument prefix The prefix to use.
00488           * @Author Joao Reis
00489           */
00490           static shared_ptr<Logger> build (const std::string& prefix);
00491           
00492           
00493           
00494           /**
00495           * @Description Sets the prefix of the ThreadSafeLogger.
00496           *
00497           * Each Logger can have exactly one prefix that is printed
00498           * before every message.
00499           * @Argument prefix The prefix to use.
00500           * @Author Joao Reis
00501           */
00502           virtual void setPrefix (const std::string& prefix);
00503           
00504           
00505           
00506           /**
00507           * @Description Enables a specific output for a specific log level.
00508           * @Argument logLevel The logLevel to associate.
00509           * @Argument logOutput The logOutput to associate with the logLevel.
00510           * @Author Joao Reis
00511           */
00512           virtual void enableLogLevel (const LogLevel& logLevel,
00513                                        shared_ptr<LogOutput> logOutput);
00514           /**
00515           * @Description Disables a specified output for a specific level.
00516           * @Argument logLevel The logOutput will be disabled only for this level.
00517           * @Argument logOutput The logOutput to disble for the logLevel.
00518           * @Author Joao Reis
00519           */
00520           virtual void disableLogLevel (const LogLevel& logLevel,
00521                                         shared_ptr<LogOutput> logOutput);
00522           /**
00523           * @Description Disables all outputs for the specified logLevel.
00524           * @Argument logLevel All the outputs of this level will be disabled.
00525           * @Author Joao Reis
00526           */
00527           virtual void disableLogLevel (const LogLevel& logLevel);
00528           
00529           
00530           
00531           /**
00532           * @Description Logs a message, given in the form of a string.
00533           *
00534           * This is the main method of the logger, all the others
00535           * just call this one internally.
00536           *
00537           * Please mind that this method is not affected by MERMAID_LOGGER_DISABLE_REPORTING.
00538           * @Argument logLevel The log level to use.
00539           * @Argument message The message to log.
00540           * @Author Joao Reis
00541           */
00542           virtual void log (const LogLevel& logLevel,
00543                             const std::string& message);
00544                             
00545                             
00546                             
00547         private:
00548           ThreadSafeLogger();
00549           ThreadSafeLogger (const std::string& prefix);
00550           
00551           ACE_RW_Mutex mutex_;
00552           int indentation_;
00553           std::string prefix_;
00554           std::map <LogLevel, std::list<shared_ptr<LogOutput> > > levelOutputs_;
00555       };
00556       
00557       
00558       
00559       /**
00560        * @Class FastLogger
00561        * @Description Fast implementation of the logger, without any thread
00562        * synchronization.
00563        * @Author Joao Reis
00564        */
00565       class FastLogger : public Logger
00566       {
00567         public:
00568           /**
00569            * @Description Creates a new FastLogger with an empty prefix.
00570            * @Returns A shared_ptr to the new Logger.
00571            * @Author Joao Reis
00572            */
00573           static shared_ptr<Logger> build();
00574           /**
00575            * @Description Creates a new FastLogger with the given prefix.
00576            * @Returns A shared_ptr to the new Logger.
00577            * @Argument prefix The prefix to use.
00578            * @Author Joao Reis
00579            */
00580           static shared_ptr<Logger> build (const std::string& prefix);
00581           
00582           
00583           
00584           /**
00585            * @Description Sets the prefix of the FastLogger.
00586            *
00587            * Each Logger can have exactly one prefix that is printed
00588            * before every message.
00589            * @Argument prefix The prefix to use.
00590            * @Author Joao Reis
00591            */
00592           virtual void setPrefix (const std::string& prefix);
00593           
00594           
00595           
00596           /**
00597            * @Description Enables a specific output for a specific log level.
00598            * @Argument logLevel The logLevel to associate.
00599            * @Argument logOutput The logOutput to associate with the logLevel.
00600            * @Author Joao Reis
00601            */
00602           virtual void enableLogLevel (const LogLevel& logLevel,
00603                                        shared_ptr<LogOutput> logOutput);
00604           /**
00605            * @Description Disables a specified output for a specific level.
00606            * @Argument logLevel The logOutput will be disabled only for this level.
00607            * @Argument logOutput The logOutput to disble for the logLevel.
00608            * @Author Joao Reis
00609            */
00610           virtual void disableLogLevel (const LogLevel& logLevel,
00611                                         shared_ptr<LogOutput> logOutput);
00612           /**
00613            * @Description Disables all outputs for the specified logLevel.
00614            * @Argument logLevel All the outputs of this level will be disabled.
00615            * @Author Joao Reis
00616            */
00617           virtual void disableLogLevel (const LogLevel& logLevel);
00618           
00619           
00620           
00621           /**
00622            * @Description Logs a message, given in the form of a string.
00623            *
00624            * This is the main method of the logger, all the others
00625            * just call this one internally.
00626            *
00627            * Please mind that this method is not affected by MERMAID_LOGGER_DISABLE_REPORTING.
00628            * @Argument logLevel The log level to use.
00629            * @Argument message The message to log.
00630            * @Author Joao Reis
00631            */
00632           virtual void log (const LogLevel& logLevel,
00633                             const std::string& message);
00634                             
00635                             
00636                             
00637         private:
00638           FastLogger();
00639           FastLogger (const std::string& prefix);
00640           
00641           int updateIndentation_ (const LogLevel& logLevel);
00642           int indentation_;
00643           std::string prefix_;
00644           std::map <LogLevel, std::list<shared_ptr<LogOutput> > > levelOutputs_;
00645 #ifdef MERMAID_LOGGER_QUICK_PROFILING
00646           std::stack<struct timeval> beginTimes_;
00647 #endif //MERMAID_LOGGER_QUICK_PROFILING
00648       };
00649       
00650       
00651       
00652       /**
00653        * @Class ThreadSafeOutput
00654        * @Description Adds mutual exclusion to another output.
00655        * @Author Joao Reis
00656        */
00657       class ThreadSafeOutput : public LogOutput
00658       {
00659         public:
00660           /**
00661            * @Description ThreadSafeOutput
00662            * @Argument output The output to guard.
00663            * @Returns A shared_ptr to the new ThreadSafeOutput.
00664            * @Author Joao Reis
00665            */
00666           static shared_ptr<ThreadSafeOutput> build (shared_ptr<LogOutput> output);
00667           /**
00668            * @Description Logs a message generated by the logger.
00669            * @Argument logMessage the message to log.
00670            * @Author Joao Reis
00671            */
00672           void outputMessage (const LogMessage& logMessage);
00673           
00674         private:
00675           ThreadSafeOutput (shared_ptr<LogOutput> output);
00676           ACE_Mutex mutex_;
00677           shared_ptr<LogOutput> output_;
00678       };
00679       
00680       
00681       
00682       /**
00683       * @Class TerminalOutput
00684       * @Description Prints LogMessage's to the standard output.
00685       * @Author Joao Reis
00686       */
00687       class TerminalOutput : public LogOutput
00688       {
00689         public:
00690           /**
00691           * @Description Gets the TerminalOutput.
00692           * Beware that the TerminalOutput is a singleton accessible only
00693           * through a ThreadSafeOutput.
00694           * @Returns A shared_ptr to the new TerminalOutput.
00695           * @Author Joao Reis
00696           */
00697           static shared_ptr<ThreadSafeOutput> build();
00698           /**
00699           * @Description Logs a message generated by the logger.
00700           * @Argument logMessage the message to log.
00701           * @Author Joao Reis
00702           */
00703           void outputMessage (const LogMessage& logMessage);
00704           
00705         private:
00706           TerminalOutput() {}
00707           static shared_ptr<ThreadSafeOutput> instance_;
00708       };
00709       
00710       
00711       
00712       /**
00713       * @Class FileOutput
00714       * @Description Appends LogMessage's to a file.
00715       * @Author Joao Reis
00716       */
00717       class FileOutput : public LogOutput
00718       {
00719         public:
00720           /**
00721           * @Description Creates a new FileOutput for the given file.
00722           * Beware that only one file output should exist for each file.
00723           * You are responsible to sychronize that output with a
00724           * ThreadSafeOutput if you need.
00725           * @Returns A shared_ptr to the new FileOutput.
00726           * @Argument fileName The name of the file to append to.
00727           * @Author Joao Reis
00728           */
00729           static shared_ptr<FileOutput> build (std::string fileName);
00730           /**
00731           * @Description Logs a message generated by the logger.
00732           * @Argument logMessage the message to log.
00733           * @Author Joao Reis
00734           */
00735           void outputMessage (const LogMessage& logMessage);
00736           
00737         private:
00738           FileOutput (std::string fileName);
00739           std::string fileName_;
00740           std::ofstream fileStream_;
00741       };
00742       
00743       
00744       
00745       /**
00746       * @Class LogScope
00747       * @Description LogScope is a helper to use the logger.
00748       *
00749       * LogScope automatically makes the end level calls
00750       * within it's destructor.
00751       * @Author Joao Reis
00752       */
00753       class LogScope
00754       {
00755         public:
00756           /**
00757           * @Description Constructor: No begin message and empty end message.
00758           * This is only used to call begin and call end automatically
00759           * when the object goes out of scope.
00760           * @Argument logger The logger to use.
00761           * @Author Joao Reis
00762           */
00763           LogScope (shared_ptr<Logger> logger);
00764           /**
00765           * @Description Constructor: Only a begin message.
00766           * @Argument logger The logger to use.
00767           * @Argument beginMessage The message to log with level LOG_BEGIN right away.
00768           * @Author Joao Reis
00769           */
00770           LogScope (shared_ptr<Logger> logger,
00771                     const std::string& beginMessage);
00772           /**
00773           * @Description Constructor: Begin and end messages.
00774           * @Argument logger The logger to use.
00775           * @Argument beginMessage The message to log with level LOG_BEGIN right away.
00776           * @Argument endMessage The message to log with level LOG_END when the class is destroyed.
00777           * @Author Joao Reis
00778           */
00779           LogScope (shared_ptr<Logger> logger,
00780                     const std::string& beginMessage,
00781                     const std::string& endMessage);
00782           ~LogScope();
00783         private:
00784           shared_ptr<Logger> logger_;
00785           std::string endMessage_;
00786           bool shouldShowMessage_;
00787           
00788           LogScope (LogScope &logScope);
00789       };
00790       
00791       
00792       
00793       namespace LogAux
00794       {
00795         using std::set;
00796         using std::string;
00797         using std::ostringstream;
00798         
00799         inline string toStr (const set<string>& strings)
00800         {
00801           ostringstream s;
00802           s << "[";
00803           bool isFirst = true;
00804           foreach (string t, strings) {
00805             if (!isFirst)
00806               s << ",";
00807             s << " " << t;
00808             isFirst = false;
00809           }
00810           s << " ]";
00811           return s.str();
00812         }
00813       }
00814       
00815       
00816       
00817       // Logger inline methods
00818       
00819       inline void Logger::log (const LogLevel& logLevel,
00820                                const mermaid::support::data::DataBox& message)
00821       {
00822         log (logLevel, static_cast<std::string> (message));
00823       }
00824       
00825       
00826       
00827       inline void Logger::error (const std::string& message)
00828       {
00829         log (LOG_ERROR, message);
00830       }
00831       inline void Logger::warn (const std::string& message)
00832       {
00833         log (LOG_WARN, message);
00834       }
00835       inline void Logger::info (const std::string& message)
00836       {
00837         log (LOG_INFO, message);
00838       }
00839 #ifndef MERMAID_LOGGER_DISABLE_REPORTING
00840       inline void Logger::begin (const std::string& message)
00841       {
00842         log (LOG_BEGIN, message);
00843       }
00844       inline void Logger::separator (const std::string& message)
00845       {
00846         log (LOG_SEPARATOR, message);
00847       }
00848       inline void Logger::step (const std::string& message)
00849       {
00850         log (LOG_STEP, message);
00851       }
00852       inline void Logger::end (const std::string& message)
00853       {
00854         log (LOG_END, message);
00855       }
00856 #else
00857       inline void Logger::begin (const std::string& message) {}
00858       inline void Logger::separator (const std::string& message) {}
00859       inline void Logger::step (const std::string& message) {}
00860       inline void Logger::end (const std::string& message) {}
00861 #endif // MERMAID_LOGGER_DISABLE_REPORTING
00862     }
00863   }
00864 }
00865 
00866 #endif // LOGGER_HPP
Generated on Fri Mar 4 22:14:58 2011 for MeRMaID::support by  doxygen 1.6.3