Implement logging abstraction (#371)

Fixes #290
This commit is contained in:
Alex Kremer
2022-11-17 23:02:16 +01:00
committed by GitHub
parent 4b8dd7b981
commit a47bf2e8fe
38 changed files with 1441 additions and 1003 deletions

View File

@@ -6,26 +6,20 @@
#undef GRPC_ASAN_ENABLED
#endif
#include <backend/BackendFactory.h>
#include <config/Config.h>
#include <etl/ReportingETL.h>
#include <log/Logger.h>
#include <webserver/Listener.h>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/json.hpp>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <algorithm>
#include <backend/BackendFactory.h>
#include <config/Config.h>
#include <cstdlib>
#include <etl/ReportingETL.h>
#include <fstream>
#include <functional>
#include <iostream>
@@ -35,7 +29,6 @@
#include <string>
#include <thread>
#include <vector>
#include <webserver/Listener.h>
using namespace clio;
@@ -80,85 +73,6 @@ parse_certs(Config const& config)
return ctx;
}
void
initLogging(Config const& config)
{
namespace src = boost::log::sources;
namespace keywords = boost::log::keywords;
namespace sinks = boost::log::sinks;
namespace trivial = boost::log::trivial;
boost::log::add_common_attributes();
std::string format = "[%TimeStamp%] [%ThreadID%] [%Severity%] %Message%";
if (config.valueOr<bool>("log_to_console", true))
{
boost::log::add_console_log(std::cout, keywords::format = format);
}
if (auto logDir = config.maybeValue<std::string>("log_directory"); logDir)
{
boost::filesystem::path dirPath{*logDir};
if (!boost::filesystem::exists(dirPath))
boost::filesystem::create_directories(dirPath);
auto const rotationSize =
config.valueOr<int64_t>("log_rotation_size", 2 * 1024) * 1024 *
1024u;
if (rotationSize <= 0)
throw std::runtime_error(
"log rotation size must be greater than 0");
auto const rotationPeriod =
config.valueOr<int64_t>("log_rotation_hour_interval", 12u);
if (rotationPeriod <= 0)
throw std::runtime_error(
"log rotation time interval must be greater than 0");
auto const dirSize =
config.valueOr<int64_t>("log_directory_max_size", 50 * 1024) *
1024 * 1024u;
if (dirSize <= 0)
throw std::runtime_error(
"log rotation directory max size must be greater than 0");
auto fileSink = boost::log::add_file_log(
keywords::file_name = dirPath / "clio.log",
keywords::target_file_name = dirPath / "clio_%Y-%m-%d_%H-%M-%S.log",
keywords::auto_flush = true,
keywords::format = format,
keywords::open_mode = std::ios_base::app,
keywords::rotation_size = rotationSize,
keywords::time_based_rotation =
sinks::file::rotation_at_time_interval(
boost::posix_time::hours(rotationPeriod)));
fileSink->locked_backend()->set_file_collector(
sinks::file::make_collector(
keywords::target = dirPath, keywords::max_size = dirSize));
fileSink->locked_backend()->scan_for_files();
}
auto const logLevel = config.valueOr<std::string>("log_level", "info");
if (boost::iequals(logLevel, "trace"))
boost::log::core::get()->set_filter(
trivial::severity >= trivial::trace);
else if (boost::iequals(logLevel, "debug"))
boost::log::core::get()->set_filter(
trivial::severity >= trivial::debug);
else if (boost::iequals(logLevel, "info"))
boost::log::core::get()->set_filter(trivial::severity >= trivial::info);
else if (
boost::iequals(logLevel, "warning") || boost::iequals(logLevel, "warn"))
boost::log::core::get()->set_filter(
trivial::severity >= trivial::warning);
else if (boost::iequals(logLevel, "error"))
boost::log::core::get()->set_filter(
trivial::severity >= trivial::error);
else if (boost::iequals(logLevel, "fatal"))
boost::log::core::get()->set_filter(
trivial::severity >= trivial::fatal);
else
{
BOOST_LOG_TRIVIAL(warning) << "Unrecognized log level: " << logLevel
<< ". Setting log level to info";
boost::log::core::get()->set_filter(trivial::severity >= trivial::info);
}
BOOST_LOG_TRIVIAL(info) << "Log level = " << logLevel;
}
void
start(boost::asio::io_context& ioc, std::uint32_t numThreads)
{
@@ -172,6 +86,7 @@ start(boost::asio::io_context& ioc, std::uint32_t numThreads)
int
main(int argc, char* argv[])
try
{
// Check command line arguments.
if (argc != 2)
@@ -196,10 +111,8 @@ main(int argc, char* argv[])
return EXIT_FAILURE;
}
initLogging(config);
BOOST_LOG_TRIVIAL(info)
<< "Clio version: " << Build::getClioFullVersionString();
LogService::init(config);
LogService::info() << "Clio version: " << Build::getClioFullVersionString();
auto ctx = parse_certs(config);
auto ctxRef = ctx
@@ -209,10 +122,10 @@ main(int argc, char* argv[])
auto const threads = config.valueOr("io_threads", 2);
if (threads <= 0)
{
BOOST_LOG_TRIVIAL(fatal) << "io_threads is less than 0";
LogService::fatal() << "io_threads is less than 0";
return EXIT_FAILURE;
}
BOOST_LOG_TRIVIAL(info) << "Number of io threads = " << threads;
LogService::info() << "Number of io threads = " << threads;
// io context to handle all incoming requests, as well as other things
// This is not the only io context in the application
@@ -258,3 +171,7 @@ main(int argc, char* argv[])
return EXIT_SUCCESS;
}
catch (std::exception const& e)
{
LogService::fatal() << "Exit on exception: " << e.what();
}