
I need to be UNICODE friendly. What is analog to BOOST_LOG for UNICODE? #pragma once /* * Copyright Alexander Sivak 2012 - 2013. */ /*! * \file logger\manster_logger.h * \author Alexander Sivak * \date 16.10.2012 * * This header contains logger class declaration. */ #pragma comment(lib, "Shlwapi.lib") // PathStripPath #include <tchar.h> #include <Shlwapi.h> #include <string> #include <boost/typeof/typeof.hpp> #include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_same.hpp> // SYSTEM // #include <string> #include <map> #include <Windows.h> // PROJECT // #include <boost/log/core.hpp> #include <boost/log/attributes.hpp> #include <boost/log/filters.hpp> #include <boost/log/formatters.hpp> #include <boost/log/sinks.hpp> #include <boost/log/utility/exception_handler.hpp> #include <boost/log/sources/exception_handler_feature.hpp> #include <boost/log/sources/channel_feature.hpp> #include <boost/thread.hpp> #include <boost/make_shared.hpp> #include <boost/scoped_ptr.hpp> #include <boost/log/trivial.hpp> #include <boost/thread/shared_mutex.hpp> // LOCAL // namespace logging = boost::log; namespace sinks = boost::log::sinks; namespace src = boost::log::sources; namespace fmt = boost::log::formatters; namespace flt = boost::log::filters; namespace attrs = boost::log::attributes; namespace keywords = boost::log::keywords; #define MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( tag_name, lg, args )\ struct tag_name\ {\ typedef lg logger_type;\ enum registration_line_t { registration_line = __LINE__ };\ static const char* registration_file() { return __FILE__; }\ static logger_type construct_logger()\ {\ return logger_type(BOOST_PP_SEQ_ENUM(args));\ }\ static inline logger_type& get()\ {\ return ::boost::log::sources::aux::logger_singleton< tag_name
::get();\ }\ };\ inline tag_name::logger_type& BOOST_JOIN(get_, tag_name)()\ {\ return tag_name::get();\ }
enum severity_level { information, warning, error, fatal }; template< typename CharT, typename TraitsT > inline std::basic_ostream< CharT, TraitsT >& operator<< ( std::basic_ostream< CharT, TraitsT >& strm, severity_level lvl) { static const char* const str[] = { "information", "warning", "error", "fatal" }; if (static_cast< std::size_t >(lvl) < (sizeof(str) / sizeof(*str))) strm << str[lvl]; else strm << static_cast< int >(lvl); return strm; } namespace manster { class logger // Non-copyconstractable and non-copyable, since scoped_ptr is used. { public: // TYPES typedef boost::shared_ptr< logger > logger_ptr; enum logger_type { db, sys, gui, inet }; // Compiler copy_ctor/dtor/operator= // OPERATIONS static logger_ptr const & instance() { if ( !instance_.get( ) ) instance_.reset( new logger( ) ); return instance_; } class manster_logger_mt; void log( logger_type const & lg_type, std::string const & logged_data ) { if ( initialized ) BOOST_LOG( loggers_map[ lg_type ] ) << logged_data.data( ); } void log( logger_type const & lg_type, std::string const & logged_data, severity_level const & lvl ) { if ( initialized ) BOOST_LOG_SEV( loggers_map[ lg_type ], lvl ) << logged_data.data( ); } void log( logger_type const & lg_type, std::wstring const & logged_data ) { if ( initialized ) BOOST_LOG( wloggers_map[ lg_type ] ) << logged_data.data( ); } void log( logger_type const & lg_type, std::wstring const & logged_data, severity_level const & lvl ) { if ( initialized ) BOOST_LOG_SEV( wloggers_map[ lg_type ], lvl ) << logged_data.data( ); } void initialize( ); // ACCESS void set_low_bound_filter( severity_level const & lvl ) { sink_ptr->set_filter( flt::attr< severity_level >( "Severity", std::nothrow) >= lvl ); } public: // TYPES // Multibyte character logger type. class manster_logger_mt : public src::basic_composite_logger< char, manster_logger_mt, // src::multi_thread_model<logging::aux::light_rw_mutex>, src::multi_thread_model< boost::shared_mutex >, src::features< src::severity< severity_level >, // src::exception_handler, src::channel< std::string > > > { BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS( manster_logger_mt ) }; // MULTIBYTE CHARACTER LOGGERS MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( logman_gui, manster_logger_mt, (keywords::severity = information)(keywords::channel = "GUI")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( logman_inet, manster_logger_mt, (keywords::severity = information)(keywords::channel = "Inet")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( logman_db, manster_logger_mt, (keywords::severity = information)(keywords::channel = "DataBase")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( logman_sys, manster_logger_mt, (keywords::severity = information)(keywords::channel = "Sys")) // Wide-character logger type. class manster_wlogger_mt : public src::basic_composite_logger< wchar_t, manster_wlogger_mt, src::multi_thread_model< boost::shared_mutex >, src::features< src::severity< severity_level >, src::channel< std::wstring > > > { BOOST_LOG_FORWARD_LOGGER_CONSTRUCTORS( manster_wlogger_mt ) }; // WIDE-BYTE LOGGERS MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( wlogman_gui, manster_wlogger_mt, (keywords::severity = information)(keywords::channel = L"GUI")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( wlogman_inet, manster_wlogger_mt, (keywords::severity = information)(keywords::channel = L"Inet")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( wlogman_db, manster_wlogger_mt, (keywords::severity = information)(keywords::channel = L"DataBase")) MANSTER_LOG_DECLARE_GLOBAL_LOGGER_ARGS_INIT( wlogman_sys, manster_wlogger_mt, (keywords::severity = information)(keywords::channel = L"Sys")) // FIELDS static bool initialized; private: // LIFECYCLE logger() : sink_ptr( boost::make_shared< file_sink > ( keywords::file_name = ".//log//%N.log" ) ) { } // FIELDS && TYPES typedef sinks::synchronous_sink< sinks::text_file_backend > file_sink; boost::shared_ptr< file_sink > sink_ptr; static logger_ptr instance_; enum byteness { unicode, multi }; typedef std::map< logger_type, manster_logger_mt > log_type_to_log; static log_type_to_log loggers_map; typedef std::map< logger_type, manster_wlogger_mt > log_type_to_wlog; static log_type_to_wlog wloggers_map; }; } typedef std::basic_string< TCHAR > stl_tchs; BOOST_TYPEOF_REGISTER_TYPE( severity_level ); BOOST_TYPEOF_REGISTER_TYPE( manster::logger::logger_type ); //! Adds line number and file name to a message. inline std::basic_string< TCHAR > locate_msg( stl_tchs const & msg, stl_tchs const & line, stl_tchs const & file ) { PathStripPath( const_cast< LPTSTR >( file.data( ) ) ); stl_tchs lm = msg; static stl_tchs const fhead = _T( " File: " ); static stl_tchs const lhead = _T( " Line: " ); lm += fhead + file + lhead + line; return lm; } //! Types. conseq: std::basic_string<TCHAR>; reason: std::basic_string<TCHAR>||char[const]*[const]. #define CONS_REAS_CONCAT( conseq, reason ) conseq + _T( ":" ) + reason typedef std::basic_string< TCHAR > stl_str; inline void LOG( stl_str const & reason, stl_str const & conseq, manster::logger::logger_type const & lgr_type, severity_level const & sev_lvl, bool const & with_file_line )\ {\ if ( ( (boost::is_convertible< BOOST_TYPEOF( reason ), std::string
::value && \ boost::is_convertible< BOOST_TYPEOF( conseq ), std::string >::value) ||\ (boost::is_convertible< BOOST_TYPEOF( reason ), std::wstring >::value && \ boost::is_convertible< BOOST_TYPEOF( conseq ), std::wstring >::value ) ) &&\ ( boost::is_same< BOOST_TYPEOF( lgr_type ), manster::logger::logger_type ::value ) &&\ ( boost::is_same< BOOST_TYPEOF( sev_lvl ), severity_level >::value ) &&\ ( boost::is_same< BOOST_TYPEOF( with_file_line ), bool >::value ) )\ manster::logger::instance( )->log(\ lgr_type,\ with_file_line ?\ locate_msg( CONS_REAS_CONCAT( conseq, reason ), boost::lexical_cast< stl_tchs >( __LINE__ ), _T( __FILE__ ) ) :\ CONS_REAS_CONCAT( conseq, reason ),\ sev_lvl );\ }
/////////////////////////////////////////////////////////// // GUI LOGGING #define LOG_GUI( reason, conseq, sev_lvl, with_file_line )\ LOG( reason, conseq, manster::logger::gui, sev_lvl, with_file_line ) #define LOG_GUI_FATAL( reason, conseq, with_file_line )\ LOG_GUI( reason, conseq, severity_level::fatal, with_file_line ) #define LOG_GUI_ERR( reason, conseq, with_file_line )\ LOG_GUI( reason, conseq, severity_level::error, with_file_line ) #define LOG_GUI_WARN( reason, conseq, with_file_line )\ LOG_GUI( reason, conseq, severity_level::warning, with_file_line ) #define LOG_GUI_INFO( reason, conseq, with_file_line )\ LOG_GUI( reason, conseq, severity_level::information, with_file_line ) /////////////////////////////////////////////////////////// // SYS LOGGING //! System type logger used. #define LOG_SYS( reason, conseq, sev_lvl, with_file_line )\ LOG( reason, conseq, manster::logger::sys, sev_lvl, with_file_line ) //! System type logger with fatal severity level used. #define LOG_SYS_FATAL( reason, conseq, with_file_line )\ LOG_SYS( reason, conseq, severity_level::fatal, with_file_line ) //! System type logger with error severity level used. #define LOG_SYS_ERR( reason, conseq, with_file_line )\ LOG_SYS( reason, conseq, severity_level::error, with_file_line ) //! System type logger with warning severity level used. #define LOG_SYS_WARN( reason, conseq, with_file_line )\ LOG_SYS( reason, conseq, severity_level::warning, with_file_line ) //! System type logger with information severity level used. #define LOG_SYS_INFO( reason, conseq, with_file_line )\ LOG_SYS( reason, conseq, severity_level::information, with_file_line ) /////////////////////////////////////////////////////////////// // CUSTOM LOGGING //! System type logger with error severity level and prede used. #define LOG_MEM_ALLOC_ERR( conseq, with_file_line )\ LOG_SYS_ERR( stl_tchs( _T( "Memory allocation failed" ) ), conseq, with_file_line ) -- View this message in context: http://boost.2283326.n4.nabble.com/Boost-log-set-channel-name-dynamically-fo... Sent from the Boost - Dev mailing list archive at Nabble.com.