From 00333a8d165dee57fbb891ece5f0dc2e259bb895 Mon Sep 17 00:00:00 2001 From: Sergey Kuznetsov Date: Mon, 21 Jul 2025 17:30:08 +0100 Subject: [PATCH] fix: Handle logger exceptions (#2349) --- src/app/ClioApplication.cpp | 2 -- src/main/Main.cpp | 2 ++ src/util/log/Logger.cpp | 34 ++++++++++++++++++++++++++++++ src/util/prometheus/Prometheus.cpp | 8 ++++++- src/util/prometheus/Prometheus.hpp | 8 +++++++ 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/src/app/ClioApplication.cpp b/src/app/ClioApplication.cpp index 34a754acf..b1137f82f 100644 --- a/src/app/ClioApplication.cpp +++ b/src/app/ClioApplication.cpp @@ -41,7 +41,6 @@ #include "util/build/Build.hpp" #include "util/config/ConfigDefinition.hpp" #include "util/log/Logger.hpp" -#include "util/prometheus/Prometheus.hpp" #include "web/AdminVerificationStrategy.hpp" #include "web/RPCServerHandler.hpp" #include "web/Server.hpp" @@ -91,7 +90,6 @@ ClioApplication::ClioApplication(util::config::ClioConfigDefinition const& confi : config_(config), signalsHandler_{config_} { LOG(util::LogService::info()) << "Clio version: " << util::build::getClioFullVersionString(); - PrometheusService::init(config); signalsHandler_.subscribeToStop([this]() { appStopper_.stop(); }); } diff --git a/src/main/Main.cpp b/src/main/Main.cpp index 4aebd3c8f..003db6482 100644 --- a/src/main/Main.cpp +++ b/src/main/Main.cpp @@ -25,6 +25,7 @@ #include "util/TerminationHandler.hpp" #include "util/config/ConfigDefinition.hpp" #include "util/log/Logger.hpp" +#include "util/prometheus/Prometheus.hpp" #include #include @@ -52,6 +53,7 @@ try { if (not app::parseConfig(run.configPath)) return EXIT_FAILURE; + PrometheusService::init(gClioConfig); if (auto const initSuccess = util::LogService::init(gClioConfig); not initSuccess) { std::cerr << initSuccess.error() << std::endl; return EXIT_FAILURE; diff --git a/src/util/log/Logger.cpp b/src/util/log/Logger.cpp index f0793705a..f0e07ec92 100644 --- a/src/util/log/Logger.cpp +++ b/src/util/log/Logger.cpp @@ -25,6 +25,9 @@ #include "util/config/ArrayView.hpp" #include "util/config/ConfigDefinition.hpp" #include "util/config/ObjectView.hpp" +#include "util/prometheus/Counter.hpp" +#include "util/prometheus/Label.hpp" +#include "util/prometheus/Prometheus.hpp" #include #include @@ -42,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -52,7 +56,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -65,6 +71,30 @@ namespace util { +namespace { + +class LoggerExceptionHandler { + std::reference_wrapper exceptionCounter_ = + PrometheusService::counterInt("logger_exceptions_total_number", util::prometheus::Labels{}); + +public: + using result_type = void; + + LoggerExceptionHandler() + { + ASSERT(PrometheusService::isInitialised(), "Prometheus should be initialised before Logger"); + } + + void + operator()(std::exception const& e) const + { + std::cerr << fmt::format("Exception in logger: {}\n", e.what()); + ++exceptionCounter_.get(); + } +}; + +} // namespace + Logger LogService::generalLog = Logger{"General"}; Logger LogService::alertLog = Logger{"Alert"}; boost::log::filter LogService::filter{}; @@ -160,6 +190,10 @@ LogService::init(config::ClioConfigDefinition const& config) sinks::file::make_collector(keywords::target = dirPath, keywords::max_size = dirSize) ); fileSink->locked_backend()->scan_for_files(); + + boost::log::core::get()->set_exception_handler( + boost::log::make_exception_handler(LoggerExceptionHandler()) + ); } // get default severity, can be overridden per channel using the `log_channels` array diff --git a/src/util/prometheus/Prometheus.cpp b/src/util/prometheus/Prometheus.cpp index dc9798e2e..0e78798eb 100644 --- a/src/util/prometheus/Prometheus.cpp +++ b/src/util/prometheus/Prometheus.cpp @@ -184,6 +184,12 @@ PrometheusService::init(util::config::ClioConfigDefinition const& config) impl = std::make_unique(enabled, compressReply); } +bool +PrometheusService::isInitialised() +{ + return impl != nullptr; +} + util::prometheus::Bool PrometheusService::boolMetric(std::string name, util::prometheus::Labels labels, std::optional description) { @@ -271,7 +277,7 @@ PrometheusService::replaceInstance(std::unique_ptr