OpenWalnut
1.2.5
|
00001 //--------------------------------------------------------------------------- 00002 // 00003 // Project: OpenWalnut ( http://www.openwalnut.org ) 00004 // 00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS 00006 // For more information see http://www.openwalnut.org/copying 00007 // 00008 // This file is part of OpenWalnut. 00009 // 00010 // OpenWalnut is free software: you can redistribute it and/or modify 00011 // it under the terms of the GNU Lesser General Public License as published by 00012 // the Free Software Foundation, either version 3 of the License, or 00013 // (at your option) any later version. 00014 // 00015 // OpenWalnut is distributed in the hope that it will be useful, 00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 // GNU Lesser General Public License for more details. 00019 // 00020 // You should have received a copy of the GNU Lesser General Public License 00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>. 00022 // 00023 //--------------------------------------------------------------------------- 00024 00025 #ifndef WLOGGER_H 00026 #define WLOGGER_H 00027 00028 #include <ostream> 00029 #include <sstream> 00030 #include <string> 00031 #include <vector> 00032 00033 #include <boost/shared_ptr.hpp> 00034 #include <boost/signals2/signal.hpp> 00035 00036 #include "WLogEntry.h" 00037 #include "WLogStream.h" 00038 #include "WStringUtils.h" 00039 #include "WSharedSequenceContainer.h" 00040 #include "WExportCommon.h" 00041 00042 /** 00043 * This class defines the interface for adding logs and managing several output streams for them. The actual log entry is in \ref WLogEntry and 00044 * the output is done in \ref WLogStream. 00045 */ 00046 class OWCOMMON_EXPORT WLogger // NOLINT 00047 { 00048 public: 00049 /** 00050 * Create the first and only instance of the logger as it is a singleton. 00051 * 00052 * \param output the output stream to use 00053 * \param level the default log level 00054 */ 00055 static void startup( std::ostream& output = std::cout, LogLevel level = LL_DEBUG ); // NOLINT - we need this non-const ref here 00056 00057 /** 00058 * Destructor. 00059 */ 00060 virtual ~WLogger(); 00061 00062 /** 00063 * Returns pointer to the currently running logger instance. 00064 * 00065 * \return pointer to logger instance. 00066 */ 00067 static WLogger* getLogger(); 00068 00069 /** 00070 * Adds a new stream to the logger. This is useful to register file streams or uncolored GUI based outputs. 00071 * \note It is not intended to allow getting streams or modifying them except you are the owner/creator. 00072 * 00073 * \param s the stream to add. 00074 */ 00075 void addStream( WLogStream::SharedPtr s ); 00076 00077 /** 00078 * Set the default format used for log entries. 00079 * 00080 * \param format the format string. See WLogEntry for details. 00081 */ 00082 void setDefaultFormat( std::string format ); 00083 00084 /** 00085 * Set the default log-level used for log entries in default console-output 00086 * 00087 * \param level the log-level 00088 */ 00089 void setDefaultLogLevel( const LogLevel& level ); 00090 00091 /** 00092 * Gets the default format used for log entries. This actually returns the format of the first log stream. 00093 * 00094 * \return format string. See WLogEntry for details. 00095 */ 00096 std::string getDefaultFormat(); 00097 00098 /** 00099 * Appends a log message to the logging queue. 00100 * \param message the log entry 00101 * \param source indicates where this entry comes from 00102 * \param level The logging level of the current message 00103 */ 00104 void addLogMessage( std::string message, std::string source = "", LogLevel level = LL_DEBUG ); 00105 00106 /** 00107 * Types of signals supported by the logger 00108 */ 00109 typedef enum 00110 { 00111 AddLog = 0 //!< for added logs 00112 } 00113 LogEvent; 00114 00115 /** 00116 * The type for all callbacks which get a log entry as parameter. 00117 */ 00118 typedef boost::function< void ( WLogEntry& ) > LogEntryCallback; 00119 00120 /** 00121 * Subscribe to the specified signal. 00122 * 00123 * \note If you want to listen to incoming log entries, you can also utilize the WLogStream class. 00124 * 00125 * \param event the kind of signal the callback should be used for. 00126 * \param callback the callback. 00127 * 00128 * \return the connection object. Disconnect it explicitly! 00129 */ 00130 boost::signals2::connection subscribeSignal( LogEvent event, LogEntryCallback callback ); 00131 00132 protected: 00133 00134 private: 00135 /** 00136 * Constructor. The logger is created using the static method startup. 00137 * 00138 * \param output the stream where to print log messages to 00139 * \param level logging level, i.e. verboseness 00140 */ 00141 WLogger( std::ostream& output, LogLevel level ); // NOLINT - we need this non-const ref here 00142 00143 /** 00144 * We do not want a copy constructor, so we define it private. 00145 */ 00146 WLogger( const WLogger& ); 00147 00148 /** 00149 * The output stream list type. 00150 */ 00151 typedef WSharedSequenceContainer< std::vector< WLogStream::SharedPtr > > Outputs; 00152 00153 /** 00154 * The list of outputs to print the messages to. 00155 */ 00156 Outputs m_outputs; 00157 00158 /** 00159 * Signal called whenever a new log message arrives. 00160 */ 00161 boost::signals2::signal< void( WLogEntry& ) > m_addLogSignal; 00162 }; 00163 00164 /** 00165 * This namespace collects several convenient access points such as wlog::err 00166 * for logging with streams to our WLogger. 00167 */ 00168 namespace wlog 00169 { 00170 /** 00171 * Resource class for streamed logging. 00172 */ 00173 class OWCOMMON_EXPORT WStreamedLogger // NOLINT 00174 { 00175 public: 00176 /** 00177 * Creates new streamed logger instance. Logging is deferred until 00178 * destruction of this instance. 00179 * 00180 * \param source Source from which the log message originates 00181 * \param level The LogLevel of the message 00182 */ 00183 WStreamedLogger( const std::string& source, LogLevel level ); 00184 00185 /** 00186 * Appends something loggable (to std::string castable) to the log. 00187 * 00188 * \param loggable Token that should be streamed into the Logger 00189 * \return The streamed logger for further use 00190 */ 00191 template< typename T > WStreamedLogger operator<<( const T& loggable ); 00192 00193 // Doxygen should ignore the TypeDef below which are just an alias for std::endl etc. 00194 // \cond Suppress_Doxygen 00195 typedef std::basic_ostream< char, std::char_traits< char > > OutStreamType; 00196 typedef OutStreamType& ( *StreamManipulatorFunctor )( OutStreamType& ); 00197 // \endcond 00198 00199 /** 00200 * This is totally crazy man! Don't get dizzy on that, watch out and 00201 * ask a C++ guru next to your side, which is probably named Christian 00202 * or have a look on that: http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator 00203 * 00204 * Allow std::endl to be streamed into log messages. 00205 * 00206 * \param manip Function pointer e.g. std::endl, std::flush, std::ends 00207 * \return The streamed logger for further use 00208 */ 00209 WStreamedLogger operator<<( StreamManipulatorFunctor manip ); 00210 00211 protected: 00212 private: 00213 /** 00214 * Actually implementing the streaming functionality. 00215 */ 00216 class Buffer 00217 { 00218 public: // NOLINT inner classes may have also lables 00219 /** 00220 * Constructs a new stream for logging. 00221 * 00222 * \param source String identifying the source of the message 00223 * \param level LogLevel of the message 00224 */ 00225 Buffer( const std::string& source, LogLevel level ); 00226 00227 /** 00228 * Commits the logging expression to our WLogger 00229 */ 00230 virtual ~Buffer(); 00231 00232 std::ostringstream m_logString; //!< queuing up parts of the log message 00233 LogLevel m_level; //!< Default logging level for this stream 00234 std::string m_source; //!< The source of the logging message 00235 }; 00236 00237 /** 00238 * Forbid assignment 00239 * 00240 * \param rhs The instance which SHOULD be copied over 00241 * \return A reference to the variable for which assignment was INTENDED. 00242 */ 00243 WStreamedLogger& operator=( const WStreamedLogger& rhs ); 00244 00245 boost::shared_ptr< Buffer > m_buffer; //!< Collects the message parts. 00246 }; 00247 00248 inline WStreamedLogger::WStreamedLogger( const std::string& source, LogLevel level ) 00249 : m_buffer( new Buffer( source, level ) ) 00250 { 00251 } 00252 00253 template< typename T > inline WStreamedLogger WStreamedLogger::operator<<( const T& loggable ) 00254 { 00255 using string_utils::operator<<; // in case we want to log arrays or vectors 00256 m_buffer->m_logString << loggable; 00257 return *this; 00258 } 00259 00260 inline WStreamedLogger WStreamedLogger::operator<<( StreamManipulatorFunctor manip ) 00261 { 00262 manip( m_buffer->m_logString ); 00263 return *this; 00264 } 00265 00266 inline WStreamedLogger::Buffer::Buffer( const std::string& source, LogLevel level ) 00267 : m_logString(), 00268 m_level( level ), 00269 m_source( source ) 00270 { 00271 } 00272 00273 /** 00274 * Convenient function for logging messages to our WLogger but not for 00275 * public use outside of this module. 00276 * 00277 * \param source Indicate the source where this log message origins. 00278 * \param level The LogLevel of this message 00279 * \return The logger created using the functions parameters 00280 */ 00281 inline WStreamedLogger _wlog( const std::string& source, LogLevel level ) 00282 { 00283 return WStreamedLogger( source, level ); 00284 } 00285 00286 /** 00287 * Logging an error message. 00288 * 00289 * \param source Indicate the source where this log message origins. 00290 * \return The logger with the error message. 00291 */ 00292 inline WStreamedLogger error( const std::string& source ) 00293 { 00294 return _wlog( source, LL_ERROR ); 00295 } 00296 00297 /** 00298 * Logging a warning message. 00299 * 00300 * \param source Indicate the source where this log message origins. 00301 * \return The logger with the warning message. 00302 */ 00303 inline WStreamedLogger warn( const std::string& source ) 00304 { 00305 return _wlog( source, LL_WARNING ); 00306 } 00307 00308 /** 00309 * Logging an information message. 00310 * 00311 * \param source Indicate the source where this log message origins. 00312 * \return The logger with the warning message. 00313 */ 00314 inline WStreamedLogger info( const std::string& source ) 00315 { 00316 return _wlog( source, LL_INFO ); 00317 } 00318 00319 /** 00320 * Logging a debug message. 00321 * 00322 * \param source Indicate the source where this log message origins. 00323 * \return The logger with the debug message. 00324 */ 00325 inline WStreamedLogger debug( const std::string& source ) 00326 { 00327 return _wlog( source, LL_DEBUG ); 00328 } 00329 } // end of namespace log 00330 00331 #endif // WLOGGER_H