Derecho  0.9
Distributed systems toolkit for RDMA
logger.cpp
Go to the documentation of this file.
1 #include <atomic>
2 #include <spdlog/async.h>
3 #include <spdlog/sinks/rotating_file_sink.h>
4 #include <spdlog/sinks/stdout_color_sinks.h>
6 #include <derecho/conf/conf.hpp>
7 
8 #define LOGGER_FACTORY_UNINITIALIZED (0)
9 #define LOGGER_FACTORY_INITIALIZING (1)
10 #define LOGGER_FACTORY_INITIALIZED (2)
11 
13 std::shared_ptr<spdlog::details::thread_pool> LoggerFactory::_thread_pool_holder;
14 std::shared_ptr<spdlog::logger> LoggerFactory::_default_logger;
15 
16 
17 std::shared_ptr<spdlog::logger> LoggerFactory::_create_logger(
18  const std::string &logger_name,
19  spdlog::level::level_enum log_level) {
20  std::vector<spdlog::sink_ptr> log_sinks;
21  log_sinks.push_back(std::make_shared<spdlog::sinks::rotating_file_sink_mt>(
22  logger_name + ".log",1L<<20, 3));
23  log_sinks.push_back(std::make_shared<spdlog::sinks::stdout_color_sink_mt>());
24  std::shared_ptr<spdlog::logger> log = std::make_shared<spdlog::async_logger>(
25  logger_name,
26  log_sinks.begin(),
27  log_sinks.end(),
29  spdlog::async_overflow_policy::block);
30  spdlog::register_logger(log);
31  log->set_pattern("[%H:%M:%S.%f] [%n] [Thread %t] [%^%l%$] %v");
32  log->set_level(log_level);
33  return log;
34 }
35 
36 // re-entrant and idempotent initializer.
38  // static initialization
39  uint32_t expected = LOGGER_FACTORY_UNINITIALIZED;
40  if (_initialize_state.compare_exchange_strong(
41  expected,LOGGER_FACTORY_INITIALIZING,std::memory_order_acq_rel)){
42  // 1 - initialize the thread pool
43  spdlog::init_thread_pool(1L<<20, 1); // 1MB buffer, 1 thread
44  _thread_pool_holder = spdlog::thread_pool();
45  // 2 - initialize the default Logger
46  std::string default_logger_name = derecho::getConfString(CONF_LOGGER_DEFAULT_LOG_NAME);
47  std::string default_log_level = derecho::getConfString(CONF_LOGGER_DEFAULT_LOG_LEVEL);
48  _default_logger = _create_logger(default_logger_name,
49  spdlog::level::from_str(default_log_level));
50  // 3 - change state to initialized
51  _initialize_state.store(LOGGER_FACTORY_INITIALIZED,std::memory_order_acq_rel);
52  auto start_ms = std::chrono::duration_cast<std::chrono::microseconds>(
53  std::chrono::high_resolution_clock::now().time_since_epoch());
54  _default_logger->debug("Program start time (microseconds): {}", start_ms.count());
55  }
56  // make sure initialization finished by concurrent callers
57  while (_initialize_state.load(std::memory_order_acquire)!=LOGGER_FACTORY_INITIALIZED) {
58  }
59 }
60 
61 std::shared_ptr<spdlog::logger> LoggerFactory::createLogger(
62  const std::string &logger_name,
63  spdlog::level::level_enum log_level) {
64  _initialize();
65  return _create_logger(logger_name,log_level);
66 }
67 
68 std::shared_ptr<spdlog::logger>& LoggerFactory::getDefaultLogger() {
69  _initialize();
70  return _default_logger;
71 }
#define LOGGER_FACTORY_INITIALIZED
Definition: logger.cpp:10
static std::shared_ptr< spdlog::logger > _default_logger
Definition: logger.hpp:16
static std::shared_ptr< spdlog::logger > createLogger(const std::string &logger_name, spdlog::level::level_enum log_level=spdlog::level::info)
Definition: logger.cpp:61
static void _initialize()
Definition: logger.cpp:37
const std::string & getConfString(const std::string &key)
Definition: conf.cpp:110
#define LOGGER_FACTORY_INITIALIZING
Definition: logger.cpp:9
static std::shared_ptr< spdlog::details::thread_pool > _thread_pool_holder
Definition: logger.hpp:15
#define LOGGER_FACTORY_UNINITIALIZED
Definition: logger.cpp:8
static std::shared_ptr< spdlog::logger > & getDefaultLogger()
Definition: logger.cpp:68
static std::atomic< uint32_t > _initialize_state
Definition: logger.hpp:14
#define CONF_LOGGER_DEFAULT_LOG_LEVEL
Definition: conf.hpp:55
#define CONF_LOGGER_DEFAULT_LOG_NAME
Definition: conf.hpp:54
static std::shared_ptr< spdlog::logger > _create_logger(const std::string &logger_name, spdlog::level::level_enum log_level)
Definition: logger.cpp:17