OpenWalnut
1.4.0
|
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 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 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 * Remove the given stream. 00079 * 00080 * \param s the stream to remove 00081 */ 00082 void removeStream( WLogStream::SharedPtr s ); 00083 00084 /** 00085 * Set the default format used for log entries. 00086 * 00087 * \param format the format string. See WLogEntry for details. 00088 */ 00089 void setDefaultFormat( std::string format ); 00090 00091 /** 00092 * Set the default log-level used for log entries in default console-output 00093 * 00094 * \param level the log-level 00095 */ 00096 void setDefaultLogLevel( const LogLevel& level ); 00097 00098 /** 00099 * Gets the default format used for log entries. This actually returns the format of the first log stream. 00100 * 00101 * \return format string. See WLogEntry for details. 00102 */ 00103 std::string getDefaultFormat(); 00104 00105 /** 00106 * Appends a log message to the logging queue. 00107 * \param message the log entry 00108 * \param source indicates where this entry comes from 00109 * \param level The logging level of the current message 00110 */ 00111 void addLogMessage( std::string message, std::string source = "", LogLevel level = LL_DEBUG ); 00112 00113 /** 00114 * Types of signals supported by the logger 00115 */ 00116 typedef enum 00117 { 00118 AddLog = 0 //!< for added logs 00119 } 00120 LogEvent; 00121 00122 /** 00123 * The type for all callbacks which get a log entry as parameter. 00124 */ 00125 typedef boost::function< void ( WLogEntry& ) > LogEntryCallback; 00126 00127 /** 00128 * Subscribe to the specified signal. 00129 * 00130 * \note If you want to listen to incoming log entries, you can also utilize the WLogStream class. 00131 * 00132 * \param event the kind of signal the callback should be used for. 00133 * \param callback the callback. 00134 * 00135 * \return the connection object. Disconnect it explicitly! 00136 */ 00137 boost::signals2::connection subscribeSignal( LogEvent event, LogEntryCallback callback ); 00138 00139 protected: 00140 private: 00141 /** 00142 * Constructor. The logger is created using the static method startup. 00143 * 00144 * \param output the stream where to print log messages to 00145 * \param level logging level, i.e. verboseness 00146 */ 00147 WLogger( std::ostream& output, LogLevel level ); // NOLINT - we need this non-const ref here 00148 00149 /** 00150 * We do not want a copy constructor, so we define it private. 00151 */ 00152 WLogger( const WLogger& ); 00153 00154 /** 00155 * The output stream list type. 00156 */ 00157 typedef WSharedSequenceContainer< std::vector< WLogStream::SharedPtr > > Outputs; 00158 00159 /** 00160 * The list of outputs to print the messages to. 00161 */ 00162 Outputs m_outputs; 00163 00164 /** 00165 * Signal called whenever a new log message arrives. 00166 */ 00167 boost::signals2::signal< void( WLogEntry& ) > m_addLogSignal; 00168 }; 00169 00170 /** 00171 * This namespace collects several convenient access points such as wlog::err 00172 * for logging with streams to our WLogger. 00173 */ 00174 namespace wlog 00175 { 00176 /** 00177 * Resource class for streamed logging. 00178 */ 00179 class WStreamedLogger // NOLINT 00180 { 00181 public: 00182 /** 00183 * Creates new streamed logger instance. Logging is deferred until 00184 * destruction of this instance. 00185 * 00186 * \param source Source from which the log message originates 00187 * \param level The LogLevel of the message 00188 */ 00189 WStreamedLogger( const std::string& source, LogLevel level ); 00190 00191 /** 00192 * Appends something loggable (to std::string castable) to the log. 00193 * 00194 * \param loggable Token that should be streamed into the Logger 00195 * \return The streamed logger for further use 00196 */ 00197 template< typename T > WStreamedLogger operator<<( const T& loggable ); 00198 00199 // Doxygen should ignore the TypeDef below which are just an alias for std::endl etc. 00200 // \cond Suppress_Doxygen 00201 typedef std::basic_ostream< char, std::char_traits< char > > OutStreamType; 00202 typedef OutStreamType& ( *StreamManipulatorFunctor )( OutStreamType& ); 00203 // \endcond 00204 00205 /** 00206 * This is totally crazy man! Don't get dizzy on that, watch out and 00207 * ask a C++ guru next to your side, which is probably named Christian 00208 * or have a look on that: http://stackoverflow.com/questions/1134388/stdendl-is-of-unknown-type-when-overloading-operator 00209 * 00210 * Allow std::endl to be streamed into log messages. 00211 * 00212 * \param manip Function pointer e.g. std::endl, std::flush, std::ends 00213 * \return The streamed logger for further use 00214 */ 00215 WStreamedLogger operator<<( StreamManipulatorFunctor manip ); 00216 00217 protected: 00218 private: 00219 /** 00220 * Actually implementing the streaming functionality. 00221 */ 00222 class Buffer 00223 { 00224 public: // NOLINT inner classes may have also lables 00225 /** 00226 * Constructs a new stream for logging. 00227 * 00228 * \param source String identifying the source of the message 00229 * \param level LogLevel of the message 00230 */ 00231 Buffer( const std::string& source, LogLevel level ); 00232 00233 /** 00234 * Commits the logging expression to our WLogger 00235 */ 00236 virtual ~Buffer(); 00237 00238 std::ostringstream m_logString; //!< queuing up parts of the log message 00239 LogLevel m_level; //!< Default logging level for this stream 00240 std::string m_source; //!< The source of the logging message 00241 }; 00242 00243 /** 00244 * Forbid assignment 00245 * 00246 * \param rhs The instance which SHOULD be copied over 00247 * \return A reference to the variable for which assignment was INTENDED. 00248 */ 00249 WStreamedLogger& operator=( const WStreamedLogger& rhs ); 00250 00251 boost::shared_ptr< Buffer > m_buffer; //!< Collects the message parts. 00252 }; 00253 00254 inline WStreamedLogger::WStreamedLogger( const std::string& source, LogLevel level ) 00255 : m_buffer( new Buffer( source, level ) ) 00256 { 00257 } 00258 00259 template< typename T > inline WStreamedLogger WStreamedLogger::operator<<( const T& loggable ) 00260 { 00261 using string_utils::operator<<; // in case we want to log arrays or vectors 00262 m_buffer->m_logString << loggable; 00263 return *this; 00264 } 00265 00266 inline WStreamedLogger WStreamedLogger::operator<<( StreamManipulatorFunctor manip ) 00267 { 00268 manip( m_buffer->m_logString ); 00269 return *this; 00270 } 00271 00272 inline WStreamedLogger::Buffer::Buffer( const std::string& source, LogLevel level ) 00273 : m_logString(), 00274 m_level( level ), 00275 m_source( source ) 00276 { 00277 } 00278 00279 /** 00280 * Convenient function for logging messages to our WLogger but not for 00281 * public use outside of this module. 00282 * 00283 * \param source Indicate the source where this log message origins. 00284 * \param level The LogLevel of this message 00285 * \return The logger created using the functions parameters 00286 */ 00287 inline WStreamedLogger _wlog( const std::string& source, LogLevel level ) 00288 { 00289 return WStreamedLogger( source, level ); 00290 } 00291 00292 /** 00293 * Logging an error message. 00294 * 00295 * \param source Indicate the source where this log message origins. 00296 * \return The logger with the error message. 00297 */ 00298 inline WStreamedLogger error( const std::string& source ) 00299 { 00300 return _wlog( source, LL_ERROR ); 00301 } 00302 00303 /** 00304 * Logging a warning message. 00305 * 00306 * \param source Indicate the source where this log message origins. 00307 * \return The logger with the warning message. 00308 */ 00309 inline WStreamedLogger warn( const std::string& source ) 00310 { 00311 return _wlog( source, LL_WARNING ); 00312 } 00313 00314 /** 00315 * Logging an information message. 00316 * 00317 * \param source Indicate the source where this log message origins. 00318 * \return The logger with the warning message. 00319 */ 00320 inline WStreamedLogger info( const std::string& source ) 00321 { 00322 return _wlog( source, LL_INFO ); 00323 } 00324 00325 /** 00326 * Logging a debug message. 00327 * 00328 * \param source Indicate the source where this log message origins. 00329 * \return The logger with the debug message. 00330 */ 00331 inline WStreamedLogger debug( const std::string& source ) 00332 { 00333 return _wlog( source, LL_DEBUG ); 00334 } 00335 } // end of namespace log 00336 00337 #endif // WLOGGER_H