From 347ef3d46dff52e18c08b366e2d989dc4cd6b914 Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Fri, 17 Sep 2021 14:35:10 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BB=D0=B0=D1=81=D1=81=D1=8B=20=D0=B8?= =?UTF-8?q?=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B6=D1=83=D1=80=D0=BD=D0=B0=D0=BB=D0=B8=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B0=D0=BD=D0=B8=D1=8F=20(=D0=BF=D1=80=D0=BE=D1=81=D1=82?= =?UTF-8?q?=D0=BE=D0=B9=20=D0=B2=D1=8B=D0=B2=D0=BE=D0=B4=20=D0=B8=20=D0=B2?= =?UTF-8?q?=20syslog)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/qt/03_message-logger/CMakeLists.txt | 53 ++++++++++++ .../qt/03_message-logger/message_logger.cpp | 29 +++++++ examples/qt/CMakeLists.txt | 1 + src/myx/qt/CMakeLists.txt | 7 ++ src/myx/qt/message_logger.hpp | 44 ++++++++++ src/myx/qt/message_logger_default.cpp | 46 +++++++++++ src/myx/qt/message_logger_default.hpp | 31 +++++++ src/myx/qt/message_logger_handler.cpp | 81 +++++++++++++++++++ src/myx/qt/message_logger_handler.hpp | 20 +++++ src/myx/qt/message_logger_syslog.cpp | 55 +++++++++++++ src/myx/qt/message_logger_syslog.hpp | 32 ++++++++ 11 files changed, 399 insertions(+) create mode 100644 examples/qt/03_message-logger/CMakeLists.txt create mode 100644 examples/qt/03_message-logger/message_logger.cpp create mode 100644 src/myx/qt/message_logger.hpp create mode 100644 src/myx/qt/message_logger_default.cpp create mode 100644 src/myx/qt/message_logger_default.hpp create mode 100644 src/myx/qt/message_logger_handler.cpp create mode 100644 src/myx/qt/message_logger_handler.hpp create mode 100644 src/myx/qt/message_logger_syslog.cpp create mode 100644 src/myx/qt/message_logger_syslog.hpp diff --git a/examples/qt/03_message-logger/CMakeLists.txt b/examples/qt/03_message-logger/CMakeLists.txt new file mode 100644 index 0000000..1348a8e --- /dev/null +++ b/examples/qt/03_message-logger/CMakeLists.txt @@ -0,0 +1,53 @@ +# Название основной цели в текущем каталоге +set(TRGT example-qt-message-logger) + +# Список файлов исходных текстов +set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/message_logger.cpp) + +if(MYXLIB_BUILD_EXAMPLES) + # Путь поиска библиотек внутри проекта + link_directories(${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}) + + # Цель для создания исполняемого файла + add_executable(${TRGT} ${TRGT_cpp}) + common_target_properties(${TRGT}) + + # Создание цели для проверки утилитой clang-tidy + add_clang_tidy_check(${TRGT} ${TRGT_cpp}) + + # Создание цели для проверки утилитой clang-analyze + add_clang_analyze_check(${TRGT} ${TRGT_cpp}) + + # Создание цели для проверки утилитой clazy + add_clazy_check(${TRGT} ${TRGT_cpp}) + + # Создание цели для проверки утилитой pvs-studio + add_pvs_check(${TRGT}) + + # Создание цели для автоматического форматирования кода + add_format_sources(${TRGT} ${TRGT_cpp}) + + # Qt5 + target_include_directories(${TRGT} PRIVATE ${CMAKE_SOURCE_DIR}/src) + target_include_directories(${TRGT} SYSTEM PUBLIC ${Qt5Core_INCLUDE_DIRS}) + + target_include_directories(${TRGT} SYSTEM PRIVATE ${CMAKE_SOURCE_DIR}/src) + add_dependencies(${TRGT} core qt) + + target_link_libraries(${TRGT} qt_static) + + target_link_libraries(${TRGT} Qt5::Core) + target_link_libraries(${TRGT} Threads::Threads) + + # Имя выходного файла для цели + set_target_properties(${TRGT} PROPERTIES OUTPUT_NAME qt-message-logger) + + add_sanitizers(${TRGT}) + + cotire(${TRGT}) + + add_dependencies(${TRGT} create_auxilary_symlinks) + + # Правила для установки + # install(TARGETS ${TRGT} COMPONENT examples RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +endif() diff --git a/examples/qt/03_message-logger/message_logger.cpp b/examples/qt/03_message-logger/message_logger.cpp new file mode 100644 index 0000000..c0bf211 --- /dev/null +++ b/examples/qt/03_message-logger/message_logger.cpp @@ -0,0 +1,29 @@ +#include +#include +#include + +#include +#include + +namespace MQ = myx::qt; +int main( int argc, char* argv[] ) +{ + QCoreApplication app( argc, argv ); + + auto mld = QSharedPointer< MQ::MessageLoggerDefault >( new MQ::MessageLoggerDefault ); + MQ::messageLoggersList.append( mld ); + MQ::messageLoggersList.append( mld ); + auto mls = QSharedPointer< MQ::MessageLoggerSyslog >( new MQ::MessageLoggerSyslog ); + MQ::messageLoggersList.append( mls ); + qInstallMessageHandler( MQ::message_logger_handler ); + + qDebug() << "Hello from process:" << QCoreApplication::applicationPid(); + qWarning() << "Warning"; + + qInstallMessageHandler( 0 ); + + qDebug() << "Reset user handlers"; + qWarning() << "Goodbye"; + + return( 0 ); +} diff --git a/examples/qt/CMakeLists.txt b/examples/qt/CMakeLists.txt index b222784..9693b8d 100644 --- a/examples/qt/CMakeLists.txt +++ b/examples/qt/CMakeLists.txt @@ -1,2 +1,3 @@ add_subdirectory(01_translators) add_subdirectory(02_posix-signal-watcher) +add_subdirectory(03_message-logger) diff --git a/src/myx/qt/CMakeLists.txt b/src/myx/qt/CMakeLists.txt index 117a821..1ff292f 100644 --- a/src/myx/qt/CMakeLists.txt +++ b/src/myx/qt/CMakeLists.txt @@ -6,6 +6,9 @@ set(TRGT qt) set(TRGT_cpp ${CMAKE_CURRENT_SOURCE_DIR}/posix_signal_watcher.cpp ${CMAKE_CURRENT_SOURCE_DIR}/translators.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_default.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_handler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_syslog.cpp ) set(TRGT_moc_hpp @@ -18,6 +21,10 @@ set(TRGT_moc_private_hpp set(TRGT_hpp ${CMAKE_CURRENT_SOURCE_DIR}/translators.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_default.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_handler.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/message_logger_syslog.hpp ) set(TRGT_headers ${TRGT_moc_hpp} ${TRGT_hpp}) diff --git a/src/myx/qt/message_logger.hpp b/src/myx/qt/message_logger.hpp new file mode 100644 index 0000000..1c44d40 --- /dev/null +++ b/src/myx/qt/message_logger.hpp @@ -0,0 +1,44 @@ +#ifndef MYX_QT_MESSAGE_LOGGER_HPP_ +#define MYX_QT_MESSAGE_LOGGER_HPP_ + +#pragma once + +#include +#include + +#include +#include +#include +#include + + +namespace myx { + +namespace qt { + +class MessageLogger +{ +public: + virtual ~MessageLogger() = default; + + virtual void debug( const QMessageLogContext& context, const QString& ) = 0; + virtual void info( const QMessageLogContext& context, const QString& ) = 0; + virtual void warning( const QMessageLogContext& context, const QString& ) = 0; + virtual void critical( const QMessageLogContext& context, const QString& ) = 0; + virtual void fatal( const QMessageLogContext& context, const QString& ) = 0; + + void setEnabled( bool v = true ) { m_enabled = v; } + bool isEnabled() { return( m_enabled ); } + +protected: + bool m_enabled { true }; +}; + +using MessageLoggersList = QList< QSharedPointer< MessageLogger > >; +extern MessageLoggersList messageLoggersList; + +} // namespace qt + +} // namespace myx + +#endif // ifndef MYX_QT_MESSAGE_LOGGER_HPP_ diff --git a/src/myx/qt/message_logger_default.cpp b/src/myx/qt/message_logger_default.cpp new file mode 100644 index 0000000..eb5cfb7 --- /dev/null +++ b/src/myx/qt/message_logger_default.cpp @@ -0,0 +1,46 @@ +#include +#include + +#include + +#include + +namespace myx { + +namespace qt { + +void MessageLoggerDefault::debug( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + fprintf( stderr, "D: %s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerDefault::info( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + fprintf( stderr, "I: %s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerDefault::warning( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + fprintf( stderr, "W: %s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerDefault::critical( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) +} + + +void MessageLoggerDefault::fatal( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) +} + +} // namespace qt + +} // namespace myx diff --git a/src/myx/qt/message_logger_default.hpp b/src/myx/qt/message_logger_default.hpp new file mode 100644 index 0000000..579ca2c --- /dev/null +++ b/src/myx/qt/message_logger_default.hpp @@ -0,0 +1,31 @@ +#ifndef MYX_QT_MESSAGE_LOGGER_DEFAULT_HPP_ +#define MYX_QT_MESSAGE_LOGGER_DEFAULT_HPP_ + +#pragma once + +#include +#include +#include + + +namespace myx { + +namespace qt { + +class MessageLoggerDefault : public MessageLogger +{ +public: + ~MessageLoggerDefault() = default; + + void debug( const QMessageLogContext& context, const QString& msg ) override; + void info( const QMessageLogContext& context, const QString& msg ) override; + void warning( const QMessageLogContext& context, const QString& msg ) override; + void critical( const QMessageLogContext& context, const QString& msg ) override; + void fatal( const QMessageLogContext& context, const QString& msg ) override; +}; + +} // namespace qt + +} // namespace myx + +#endif // ifndef MYX_QT_MESSAGE_LOGGER_DEFAULT_HPP_ diff --git a/src/myx/qt/message_logger_handler.cpp b/src/myx/qt/message_logger_handler.cpp new file mode 100644 index 0000000..141dbbf --- /dev/null +++ b/src/myx/qt/message_logger_handler.cpp @@ -0,0 +1,81 @@ +#include +#include + +#include + +#include + +namespace myx { + +namespace qt { + +MessageLoggersList messageLoggersList; + +void message_logger_handler( QtMsgType type, const QMessageLogContext& context, const QString& msg ) +{ + if ( messageLoggersList.isEmpty() ) + { + QByteArray localMsg = msg.toLocal8Bit(); + const char* file = context.file ? context.file : ""; + const char* function = context.function ? context.function : ""; + switch ( type ) + { + case QtDebugMsg: + #ifndef QT_NO_DEBUG_OUTPUT +// fprintf( stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function ); + fprintf( stderr, "%s\n", localMsg.constData() ); + #endif + break; + case QtInfoMsg: + #ifndef QT_NO_INFO_OUTPUT +// fprintf( stderr, "Info: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function ); + fprintf( stderr, "%s\n", localMsg.constData() ); + #endif + break; + case QtWarningMsg: + #ifndef QT_NO_WARNING_OUTPUT +// fprintf( stderr, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function ); + fprintf( stderr, "%s\n", localMsg.constData() ); + #endif + break; + case QtCriticalMsg: +// fprintf( stderr, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function ); + fprintf( stderr, "%s\n", localMsg.constData() ); + break; + case QtFatalMsg: +// fprintf( stderr, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), file, context.line, function ); + fprintf( stderr, "%s\n", localMsg.constData() ); + break; + } // switch + } + else + { + switch ( type ) + { + case QtDebugMsg: + for ( auto& m: qAsConst( messageLoggersList ) ) + { if ( m->isEnabled() ) { m->debug( context, msg ); } } + break; + case QtInfoMsg: + for ( auto& m: qAsConst( messageLoggersList ) ) + { if ( m->isEnabled() ) { m->info( context, msg ); } } + break; + case QtWarningMsg: + for ( auto& m: qAsConst( messageLoggersList ) ) + { if ( m->isEnabled() ) { m->warning( context, msg ); } } + break; + case QtCriticalMsg: + for ( auto& m: qAsConst( messageLoggersList ) ) + { if ( m->isEnabled() ) { m->critical( context, msg ); } } + break; + case QtFatalMsg: + for ( auto& m: qAsConst( messageLoggersList ) ) + { if ( m->isEnabled() ) { m->fatal( context, msg ); } } + break; + } // switch + } +} // message_logger_handler + +} // namespace qt + +} // namespace myx diff --git a/src/myx/qt/message_logger_handler.hpp b/src/myx/qt/message_logger_handler.hpp new file mode 100644 index 0000000..1a4ba69 --- /dev/null +++ b/src/myx/qt/message_logger_handler.hpp @@ -0,0 +1,20 @@ +#ifndef MYX_QT_MESSAGE_LOGGER_HANDLER_HPP_ +#define MYX_QT_MESSAGE_LOGGER_HANDLER_HPP_ + +#pragma once + +#include +#include +#include + +namespace myx { + +namespace qt { + +void message_logger_handler( QtMsgType type, const QMessageLogContext& context, const QString& msg ); + +} // namespace qt + +} // namespace myx + +#endif // ifndef MYX_QT_MESSAGE_LOGGER_HANDLER_HPP_ diff --git a/src/myx/qt/message_logger_syslog.cpp b/src/myx/qt/message_logger_syslog.cpp new file mode 100644 index 0000000..9782dbd --- /dev/null +++ b/src/myx/qt/message_logger_syslog.cpp @@ -0,0 +1,55 @@ +#include +#include + +#include + +#include + +namespace myx { + +namespace qt { + +MessageLoggerSyslog::MessageLoggerSyslog() : + MessageLogger() +{ +// openlog( nullptr, LOG_ODELAY, LOG_USER ); +} + + +void MessageLoggerSyslog::debug( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + syslog( LOG_DEBUG, "%s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerSyslog::info( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + syslog( LOG_INFO, "%s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerSyslog::warning( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + syslog( LOG_WARNING, "%s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerSyslog::critical( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + syslog( LOG_CRIT, "%s\n", msg.toUtf8().data() ); +} + + +void MessageLoggerSyslog::fatal( const QMessageLogContext& context, const QString& msg ) +{ + Q_UNUSED( context ) + syslog( LOG_EMERG, "%s\n", msg.toUtf8().data() ); +} + +} // namespace qt + +} // namespace myx diff --git a/src/myx/qt/message_logger_syslog.hpp b/src/myx/qt/message_logger_syslog.hpp new file mode 100644 index 0000000..423a283 --- /dev/null +++ b/src/myx/qt/message_logger_syslog.hpp @@ -0,0 +1,32 @@ +#ifndef MYX_QT_MESSAGE_LOGGER_SYSLOG_HPP_ +#define MYX_QT_MESSAGE_LOGGER_SYSLOG_HPP_ + +#pragma once + +#include +#include +#include + + +namespace myx { + +namespace qt { + +class MessageLoggerSyslog : public MessageLogger +{ +public: + MessageLoggerSyslog(); + ~MessageLoggerSyslog() = default; + + void debug( const QMessageLogContext& context, const QString& msg ) override; + void info( const QMessageLogContext& context, const QString& msg ) override; + void warning( const QMessageLogContext& context, const QString& msg ) override; + void critical( const QMessageLogContext& context, const QString& msg ) override; + void fatal( const QMessageLogContext& context, const QString& msg ) override; +}; + +} // namespace qt + +} // namespace myx + +#endif // ifndef MYX_QT_MESSAGE_LOGGER_SYSLOG_HPP_