diff --git a/src/log/CMakeLists.txt b/src/log/CMakeLists.txt index 8826ed1..800f7e8 100644 --- a/src/log/CMakeLists.txt +++ b/src/log/CMakeLists.txt @@ -4,11 +4,13 @@ set(current_target log) # Список файлов исходных текстов set(current_target_sources ${CMAKE_CURRENT_SOURCE_DIR}/spdlog.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/spdlog_qt.cpp ) # Список заголовочных файлов (используется для установки) set(current_target_headers ${CMAKE_CURRENT_SOURCE_DIR}/spdlog.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/spdlog_qt.hpp ) add_common_library(TARGET ${current_target} SOURCES ${current_target_sources}) diff --git a/src/log/spdlog.cpp b/src/log/spdlog.cpp index 60bf5e2..3bcf87b 100644 --- a/src/log/spdlog.cpp +++ b/src/log/spdlog.cpp @@ -1,11 +1,3 @@ -#include - -#include -#include -#include -#include -#include - #include "config.hpp" #include "spdlog.hpp" @@ -13,84 +5,246 @@ namespace myx { namespace log { -static std::shared_ptr< spdlog::logger > logger = nullptr; -static std::shared_ptr< spdlog::logger > logger_mt = nullptr; +static Logger defaultLogger( "default" ); std::shared_ptr< spdlog::logger > default_logger() { - return( logger ); + return( static_cast< std::shared_ptr< spdlog::logger > >( defaultLogger.logger() ) ); } -std::shared_ptr< spdlog::logger > default_mt_logger() +spdlog::level::level_enum Logger::outputLevel() const { - return( logger_mt ); + return( m_outputLevel ); } -void spdlog_init() +void Logger::setOutputLevel( const spdlog::level::level_enum& outputLevel ) { - auto nameSt = fmt::format( "{}_{}", PROJECT_NAME, "st" ); - auto sinksSt = std::make_shared< std::vector< spdlog::sink_ptr > >(); - - #ifndef RELEASE - sinksSt->push_back( std::make_shared< spdlog::sinks::ansicolor_stdout_sink_st >() ); - sinksSt->push_back( std::make_shared< spdlog::sinks::daily_file_sink_st >( nameSt, 23, 59 ) ); - #endif - sinksSt->push_back( std::make_shared< spdlog::sinks::syslog_sink_st >( nameSt ) ); - logger = std::make_shared< spdlog::logger >( nameSt, sinksSt->begin(), sinksSt->end() ); - logger->flush_on( spdlog::level::warn ); - spdlog::register_logger( logger ); - - spdlog::init_thread_pool( 128, 1 ); - auto nameMt = fmt::format( "{}_{}", PROJECT_NAME, "mt" ); - auto sinksMt = std::make_shared< std::vector< spdlog::sink_ptr > >(); - #ifndef RELEASE - sinksMt->push_back( std::make_shared< spdlog::sinks::ansicolor_stdout_sink_mt >() ); - sinksMt->push_back( std::make_shared< spdlog::sinks::daily_file_sink_mt >( nameMt, 23, 59 ) ); - #endif - sinksMt->push_back( std::make_shared< spdlog::sinks::syslog_sink_mt >( nameMt ) ); - logger_mt = std::make_shared< spdlog::async_logger >( nameMt, sinksMt->begin(), sinksMt->end(), spdlog::thread_pool() ); - logger_mt->flush_on( spdlog::level::warn ); - spdlog::register_logger( logger_mt ); - - #ifndef QT_NO_DEBUG - spdlog::set_level( spdlog::level::debug ); - #endif -} // spdlog_init + m_outputLevel = outputLevel; +} -void qt_message_handler( QtMsgType type, const QMessageLogContext& context, const QString& qMsg ) +spdlog::level::level_enum Logger::flushLevel() const { - if ( !logger ) - { - return; - } - Q_UNUSED( context ) + return( m_flushLevel ); +} - const char* msg = qMsg.toUtf8().constData(); - switch ( type ) +void Logger::setFlushLevel( const spdlog::level::level_enum& flushLevel ) +{ + m_flushLevel = flushLevel; +} + + +Logger::Logger( const std::string& name ) : + m_name( name ), + m_logger( name, nullptr ), + m_baseFileName( fmt::format( "{}_{}", PROJECT_NAME, "st" ) ), + m_maxRotatingFileSize( 256 * 1024 ), + m_maxRotatingFilesCount( 3 ), + m_outputLevel( spdlog::level::trace ), + m_flushLevel( spdlog::level::warn ), + m_nullSink( nullptr ), + m_stdoutSink( nullptr ), + m_stderrSink( nullptr ), + m_syslogSink( nullptr ), + m_basicFileSink( nullptr ), + m_rotatingFileSink( nullptr ), + m_dailyFileSink( nullptr ) +{ + m_logger.flush_on( m_flushLevel ); + m_logger.set_level( m_outputLevel ); + spdlog::register_logger( logger() ); + spdlog::set_default_logger( logger() ); +} + + +std::shared_ptr< spdlog::logger > Logger::logger() +{ + return( static_cast< std::shared_ptr< spdlog::logger > >( &m_logger ) ); +} + + +std::string Logger::name() const +{ + return( m_name ); +} + + +void Logger::setName( const std::string& name ) +{ + m_name = name; +} + + +std::string Logger::baseFileName() const +{ + return( m_baseFileName ); +} + + +void Logger::setBaseFileName( const std::string& baseFileName ) +{ + m_baseFileName = baseFileName; +} + + +void Logger::enableNullSink() +{ + if ( m_nullSink == nullptr ) { - case QtDebugMsg: - logger->debug( msg ); - break; - case QtInfoMsg: - logger->info( msg ); - break; - case QtWarningMsg: - logger->warn( msg ); - break; - case QtCriticalMsg: - logger->critical( msg ); - break; - case QtFatalMsg: - logger->critical( "FATAL: %s", msg ); - QCoreApplication::exit( 1 ); - break; + m_nullSink = std::make_shared< spdlog::sinks::null_sink_st >(); + m_logger.sinks().push_back( m_nullSink ); } -} // messageHandler +} + + +void Logger::disableNullSink() +{ + if ( m_nullSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_nullSink ), + m_logger.sinks().end() ); + m_nullSink.reset(); + m_nullSink = nullptr; + } +} + + +void Logger::enableStdoutSink() +{ + if ( m_stdoutSink == nullptr ) + { + m_stdoutSink = std::make_shared< spdlog::sinks::ansicolor_stdout_sink_st >(); + m_logger.sinks().push_back( m_stdoutSink ); + } +} + + +void Logger::disableStdoutSink() +{ + if ( m_stdoutSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_stdoutSink ), + m_logger.sinks().end() ); + m_stdoutSink.reset(); + m_stdoutSink = nullptr; + } +} + + +void Logger::enableStderrSink() +{ + if ( m_stderrSink == nullptr ) + { + m_stderrSink = std::make_shared< spdlog::sinks::ansicolor_stderr_sink_st >(); + m_logger.sinks().push_back( m_stderrSink ); + } +} + + +void Logger::disableStderrSink() +{ + if ( m_stderrSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_stderrSink ), + m_logger.sinks().end() ); + m_stderrSink.reset(); + m_stderrSink = nullptr; + } +} + + +void Logger::enableSyslogSink() +{ + if ( m_syslogSink == nullptr ) + { + m_syslogSink = std::make_shared< spdlog::sinks::syslog_sink_st >(); + m_logger.sinks().push_back( m_syslogSink ); + } +} + + +void Logger::disableSyslogSink() +{ + if ( m_syslogSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_syslogSink ), + m_logger.sinks().end() ); + m_syslogSink.reset(); + m_syslogSink = nullptr; + } +} + + +void Logger::enableBasicFileSink() +{ + if ( m_basicFileSink == nullptr ) + { + m_basicFileSink = std::make_shared< spdlog::sinks::basic_file_sink_st >( m_baseFileName ); + m_logger.sinks().push_back( m_basicFileSink ); + } +} + + +void Logger::disableBasicFileSink() +{ + if ( m_basicFileSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_basicFileSink ), + m_logger.sinks().end() ); + m_basicFileSink.reset(); + m_basicFileSink = nullptr; + } +} + + +void Logger::enableRotatingFileSink() +{ + if ( m_rotatingFileSink == nullptr ) + { + m_rotatingFileSink = std::make_shared< spdlog::sinks::rotating_file_sink_st >( m_baseFileName, m_maxRotatingFileSize, m_maxRotatingFilesCount ); + m_logger.sinks().push_back( m_rotatingFileSink ); + } +} + + +void Logger::disableRotatingFileSink() +{ + if ( m_rotatingFileSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_rotatingFileSink ), + m_logger.sinks().end() ); + m_rotatingFileSink.reset(); + m_rotatingFileSink = nullptr; + } +} + + +void Logger::enableDailyFileSink() +{ + if ( m_dailyFileSink == nullptr ) + { + const int rotationHour = 23; + const int rotationMinute = 59; + m_dailyFileSink = std::make_shared< spdlog::sinks::daily_file_sink_st >( m_baseFileName, rotationHour, rotationMinute ); + m_logger.sinks().push_back( m_dailyFileSink ); + } +} + + +void Logger::disableDailyFileSink() +{ + if ( m_dailyFileSink != nullptr ) + { + m_logger.sinks().erase( std::remove( m_logger.sinks().begin(), m_logger.sinks().end(), m_dailyFileSink ), + m_logger.sinks().end() ); + m_dailyFileSink.reset(); + m_dailyFileSink = nullptr; + } +} } // namespace log diff --git a/src/log/spdlog.hpp b/src/log/spdlog.hpp index fecdad5..d89f52e 100644 --- a/src/log/spdlog.hpp +++ b/src/log/spdlog.hpp @@ -1,18 +1,70 @@ #ifndef MYX_LOG_SPDLOG_HPP_ #define MYX_LOG_SPDLOG_HPP_ -#include -#include -#include +#include +#include +#include +#include +#include +// #include +// #include namespace myx { namespace log { -void spdlog_init(); +class Logger +{ + std::string m_name; + spdlog::logger m_logger; + std::string m_baseFileName; + std::size_t m_maxRotatingFileSize; + std::size_t m_maxRotatingFilesCount; + spdlog::level::level_enum m_outputLevel; + spdlog::level::level_enum m_flushLevel; + std::shared_ptr < spdlog::sinks::null_sink_st > m_nullSink; + std::shared_ptr< spdlog::sinks::ansicolor_stdout_sink_st > m_stdoutSink; + std::shared_ptr< spdlog::sinks::ansicolor_stderr_sink_st > m_stderrSink; + std::shared_ptr< spdlog::sinks::syslog_sink_st > m_syslogSink; + std::shared_ptr< spdlog::sinks::basic_file_sink_st > m_basicFileSink; + std::shared_ptr< spdlog::sinks::rotating_file_sink_st > m_rotatingFileSink; + std::shared_ptr< spdlog::sinks::daily_file_sink_st > m_dailyFileSink; + +public: + Logger( const std::string& name ); + + std::shared_ptr< spdlog::logger > logger(); + std::string name() const; + void setName( const std::string& name ); + std::string baseFileName() const; + void setBaseFileName( const std::string& baseFileName ); + + void enableNullSink(); + void disableNullSink(); + void enableStdoutSink(); + void disableStdoutSink(); + void enableStderrSink(); + void disableStderrSink(); + void enableSyslogSink(); + void disableSyslogSink(); + void enableBasicFileSink(); + void disableBasicFileSink(); + void enableRotatingFileSink(); + void disableRotatingFileSink(); + void enableDailyFileSink(); + void disableDailyFileSink(); + spdlog::level::level_enum outputLevel() const; + void setOutputLevel( const spdlog::level::level_enum& outputLevel ); + spdlog::level::level_enum flushLevel() const; + void setFlushLevel( const spdlog::level::level_enum& flushLevel ); +}; // class Logger + + +/** + * @brief default_logger + * @return + */ std::shared_ptr< spdlog::logger > default_logger(); -std::shared_ptr< spdlog::logger > default_mt_logger(); -void qt_message_handler( QtMsgType type, const QMessageLogContext& context, const QString& qMsg ); template < class F, class ... Args >