diff options
Diffstat (limited to 'src/liblogger/Logger.cpp')
-rwxr-xr-x | src/liblogger/Logger.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/src/liblogger/Logger.cpp b/src/liblogger/Logger.cpp new file mode 100755 index 0000000..c4d44d8 --- /dev/null +++ b/src/liblogger/Logger.cpp @@ -0,0 +1,183 @@ +#include "Logger.hpp" +#include "LogSink.hpp" +#include "ConsoleLogSink.hpp" +#include "FileLogSink.hpp" +#include "SyslogLogSink.hpp" +#ifdef _WIN32 +#include "WinDbgLogSink.hpp" +#endif + +#include <algorithm> +#include <list> + +using namespace std; + +LogStream::LogStream( Logger &logger, const LogLevel level ) + : m_logger( logger ), m_level( level ) +{ +} + +LogStream::~LogStream( ) +{ + m_logger.log( m_level, str( ) ); +} + +ostream &LogStream::get( ) +{ + // transform the ostringstream to ostream, so the operator + // << functions work a little bit more as expected (e.g. + // for strings/char *) + return static_cast<ostream &>( *this ); +} + +class LoggerImpl +{ + public: + void addSink( LogSink *sink ); + void removeSink( LogSink *sink ); + void log( const LogLevel level, const std::string &msg ); + + static std::string toString( const LogLevel level ); + static LogLevel fromString( const std::string &s ); + + void openConsoleLog( const LogLevel level ); + void openFileLog( const LogLevel level, const std::string &filename ); + void openSyslog( const LogLevel level, const string &ident, const string &facility ); + void openWinDbgLog( const LogLevel level ); + + public: + LoggerImpl( ); + ~LoggerImpl( ); + + private: + typedef std::list< LogSink * > SinkList; + SinkList m_sinks; +}; + +LoggerImpl::LoggerImpl( ) +{ +} + +LoggerImpl::~LoggerImpl( ) +{ + SinkList::const_iterator it, end = m_sinks.end( ); + + for( it = m_sinks.begin( ); it != end; it++ ) { + delete (*it); + } +} + +void LoggerImpl::addSink( LogSink *sink ) +{ + m_sinks.push_back( sink ); +} +void LoggerImpl::removeSink( LogSink *sink ) +{ + SinkList::iterator it = find( m_sinks.begin( ), m_sinks.end( ), sink ); + if( it != m_sinks.end( ) ) { + m_sinks.erase( it ); + } +} + +void LoggerImpl::log( const LogLevel level, const string &msg ) +{ + SinkList::const_iterator it, end = m_sinks.end( ); + + for( it = m_sinks.begin( ); it != end; it++ ) { + (*it)->log( level, msg ); + } +} + +void LoggerImpl::openConsoleLog( const LogLevel level ) +{ + addSink( new ConsoleLogSink( level ) ); +} + +void LoggerImpl::openFileLog( const LogLevel level, const string &filename ) +{ + addSink( new FileLogSink( level, filename ) ); +} + +void LoggerImpl::openSyslog( const LogLevel level, const string &ident, const string &facility ) +{ + addSink( new SyslogLogSink( level, ident, facility ) ); +} + +void LoggerImpl::openWinDbgLog( const LogLevel level ) +{ +#ifdef _WIN32 + addSink( new WinDbgLogSink( level ) ); +#else + (void)level; + LOG( logWARNING ) << "WinDbg logger is only available on Windows"; +#endif +} + +string Logger::toString( const LogLevel level ) +{ + static const char* const buf[] = { "NONE", "FATAL", "CRITICAL", "ERROR", "WARNING", "NOTICE", "INFO", "DEBUG", "DEBUG1", "DEBUG2", "DEBUG3", "DEBUG4" }; + return buf[level]; +} + +LogLevel Logger::fromString( const string& level ) +{ + if( level == "DEBUG4" ) return logDEBUG4; + if( level == "DEBUG3" ) return logDEBUG3; + if( level == "DEBUG2" ) return logDEBUG2; + if( level == "DEBUG1") return logDEBUG1; + if( level == "DEBUG") return logDEBUG; + if( level == "INFO") return logINFO; + if( level == "NOTICE" ) return logNOTICE; + if( level == "WARNING" ) return logWARNING; + if( level == "ERROR" ) return logERROR; + if( level == "CRITICAL" ) return logCRITICAL; + if( level == "FATAL" ) return logFATAL; + if( level == "NONE" ) return logNONE; + + LOG( logWARNING ) << "Unknown log level '" << level << "'. Using INFO level as default."; + return logINFO; +} + +Logger::Logger( ) +{ + m_impl.reset( new LoggerImpl( ) ); +} + +Logger::~Logger( ) +{ +} + +void Logger::addSink( LogSink *sink ) +{ + m_impl->addSink( sink ); +} + +void Logger::removeSink( LogSink *sink ) +{ + m_impl->removeSink( sink ); +} + +void Logger::log( const LogLevel level, const string &msg ) +{ + m_impl->log( level, msg ); +} + +void Logger::openConsoleLog( const LogLevel level ) +{ + m_impl->openConsoleLog( level ); +} + +void Logger::openFileLog( const LogLevel level, const std::string &filename ) +{ + m_impl->openFileLog( level, filename ); +} + +void Logger::openSyslog( const LogLevel level, const string &ident, const string &facility ) +{ + m_impl->openSyslog( level, ident, facility ); +} + +void Logger::openWinDbgLog( const LogLevel level ) +{ + m_impl->openWinDbgLog( level ); +} |