diff --git a/src/utils/fmt_logging.h b/src/utils/fmt_logging.h index 8971de3168..0059d3e44e 100644 --- a/src/utils/fmt_logging.h +++ b/src/utils/fmt_logging.h @@ -27,46 +27,47 @@ #include "spdlog/common.h" #include "spdlog/spdlog.h" +extern std::shared_ptr stderr_logger; +extern std::shared_ptr file_logger; + #define LOG(level, ...) \ do { \ if (level >= log_start_level) \ - spdlog::log(level, __VA_ARGS__); \ + file_logger->log(level, __VA_ARGS__); \ } while (false) -extern std::shared_ptr stderr_logger; -extern std::shared_ptr file_logger; extern spdlog::level::level_enum stderr_start_level; #define LOG_DEBUG(...) \ do { \ - SPDLOG_DEBUG(__VA_ARGS__); \ + SPDLOG_LOGGER_DEBUG(file_logger, __VA_ARGS__); \ if (spdlog::level::debug >= stderr_start_level) { \ SPDLOG_LOGGER_DEBUG(stderr_logger, __VA_ARGS__); \ } \ } while (false) #define LOG_INFO(...) \ do { \ - SPDLOG_INFO(__VA_ARGS__); \ + SPDLOG_LOGGER_INFO(file_logger, __VA_ARGS__); \ if (spdlog::level::info >= stderr_start_level) { \ SPDLOG_LOGGER_INFO(stderr_logger, __VA_ARGS__); \ } \ } while (false) #define LOG_WARNING(...) \ do { \ - SPDLOG_WARN(__VA_ARGS__); \ + SPDLOG_LOGGER_WARN(file_logger, __VA_ARGS__); \ if (spdlog::level::warn >= stderr_start_level) { \ SPDLOG_LOGGER_WARN(stderr_logger, __VA_ARGS__); \ } \ } while (false) #define LOG_ERROR(...) \ do { \ - SPDLOG_ERROR(__VA_ARGS__); \ + SPDLOG_LOGGER_ERROR(file_logger, __VA_ARGS__); \ if (spdlog::level::err >= stderr_start_level) { \ SPDLOG_LOGGER_ERROR(stderr_logger, __VA_ARGS__); \ } \ } while (false) #define LOG_FATAL(...) \ do { \ - SPDLOG_CRITICAL(__VA_ARGS__); \ + SPDLOG_LOGGER_CRITICAL(file_logger, __VA_ARGS__); \ if (spdlog::level::critical >= stderr_start_level) { \ SPDLOG_LOGGER_CRITICAL(stderr_logger, __VA_ARGS__); \ } \ diff --git a/src/utils/logging.cpp b/src/utils/logging.cpp index 33618fdc1b..a69db4de98 100644 --- a/src/utils/logging.cpp +++ b/src/utils/logging.cpp @@ -75,6 +75,15 @@ DSN_DEFINE_validator(max_number_of_log_files_on_disk, [](int32_t value) -> bool { return value > 0; }); DSN_DEFINE_string(tools.simple_logger, base_name, "pegasus", "The default base name for log file"); +DSN_DEFINE_string( + tools.simple_logger, + stderr_start_level, + "LOG_LEVEL_WARNING", + "The lowest level of log messages to be copied to stderr in addition to log files"); +DSN_DEFINE_validator(stderr_start_level, [](const char *value) -> bool { + const auto level = enum_from_string(value, LOG_LEVEL_INVALID); + return LOG_LEVEL_DEBUG <= level && level <= LOG_LEVEL_FATAL; +}); spdlog::level::level_enum log_start_level = spdlog::level::info; @@ -82,11 +91,6 @@ namespace dsn { using namespace tools; } // namespace dsn -static void log_on_sys_exit(::dsn::sys_exit_type) -{ - dsn::logging_provider *logger = dsn::logging_provider::instance(); - logger->flush(); -} std::shared_ptr file_logger; void dsn_log_init(const std::string &log_dir, const std::string &role_name, @@ -103,24 +107,17 @@ void dsn_log_init(const std::string &log_dir, // CHECK_NE_MSG( // log_start_level, LOG_LEVEL_INVALID, "invalid [core] logging_start_level specified"); - spdlog::set_level(spdlog::level::info); - spdlog::flush_on(spdlog::level::err); + file_logger->set_level(spdlog::level::info); + file_logger->flush_on(spdlog::level::err); if (FLAGS_fast_flush) { spdlog::flush_every(std::chrono::seconds(1)); } // register log flush on exit if (FLAGS_logging_flush_on_exit) { - ::dsn::tools::sys_exit.put_back(log_on_sys_exit, "log.flush"); +// ::dsn::tools::sys_exit.put_back(log_on_sys_exit, "log.flush"); } - // // The leading character of each log line, corresponding to the log level - // // D: Debug - // // I: Info - // // W: Warning - // // E: Error - // // F: Fatal - // static char s_level_char[] = "DIWEF"; // // uint64_t ts = dsn_now_ns(); // std::string time_str; @@ -130,11 +127,17 @@ void dsn_log_init(const std::string &log_dir, // const auto header = fmt::format( // "{}{} ({} {}) {}", s_level_char[log_level], time_str, ts, tid, // log_prefixed_message_func()); + // The leading character of each log line, corresponding to the log level + // D: Debug + // I: Info + // W: Warning + // E: Error + // C: Critical if (FLAGS_short_header) { - spdlog::set_pattern("[:%Y-%m-%d %H:%M:%S %z] [%^%L%$] [thread %t] %v"); + file_logger->set_pattern("[%^%L%$%Y-%m-%d %H:%M:%S %z] [thread %t] %v"); } else { // const auto long_header = fmt::format("{}:{}:{}(): ", file, line, function); - spdlog::set_pattern("[:%Y-%m-%d %H:%M:%S %z] [%^%L%$] [thread %t] %v"); + file_logger->set_pattern("[%^%L%$%Y-%m-%d %H:%M:%S %z] [thread %t] %v"); } // Flush when exit @@ -146,23 +149,3 @@ void dsn_log_init(const std::string &log_dir, spdlog::level::level_enum get_log_start_level() { return log_start_level; } void set_log_start_level(spdlog::level::level_enum level) { log_start_level = level; } - -namespace dsn { - -std::unique_ptr logging_provider::_logger; - -logging_provider *logging_provider::instance() { return _logger ? _logger.get() : nullptr; } - -void logging_provider::set_logger(logging_provider *logger) { _logger.reset(logger); } - -namespace tools { -namespace internal_use_only { -bool register_component_provider(const char *name, - logging_provider::factory f, - ::dsn::provider_type type) -{ - return dsn::utils::factory_store::register_factory(name, f, type); -} -} // namespace internal_use_only -} // namespace tools -} // namespace dsn diff --git a/src/utils/logging_provider.h b/src/utils/logging_provider.h index 1c4164e3d8..65d2437d87 100644 --- a/src/utils/logging_provider.h +++ b/src/utils/logging_provider.h @@ -30,54 +30,6 @@ #include "utils/command_manager.h" #include "utils/factory_store.h" -namespace dsn { - -/*! -@addtogroup tool-api-providers -@{ -*/ -class logging_provider -{ -public: - template - static logging_provider *create(const char *log_dir, const char *role_name) - { - return new T(log_dir, role_name); - } - - typedef logging_provider *(*factory)(const char *, const char *); - -public: - virtual ~logging_provider() = default; - - // singleton - static logging_provider *instance(); - - // not thread-safe - static void set_logger(logging_provider *logger); - - virtual void flush() = 0; - - void deregister_commands() { _cmds.clear(); } - -protected: - static std::unique_ptr _logger; - - logging_provider(log_level_t stderr_start_level) : _stderr_start_level(stderr_start_level) {} - - std::vector> _cmds; - const log_level_t _stderr_start_level; -}; - -namespace tools { -namespace internal_use_only { -bool register_component_provider(const char *name, - logging_provider::factory f, - ::dsn::provider_type type); -} // namespace internal_use_only -} // namespace tools -} // namespace dsn - extern void dsn_log_init(const std::string &log_dir, const std::string &role_name, const std::function &dsn_log_prefixed_message_func); diff --git a/src/utils/simple_logger.cpp b/src/utils/simple_logger.cpp index 8f2273606b..a66cc1859d 100644 --- a/src/utils/simple_logger.cpp +++ b/src/utils/simple_logger.cpp @@ -56,23 +56,12 @@ #include "utils/strings.h" #include "utils/time_utils.h" -DSN_DEFINE_string( - tools.simple_logger, - stderr_start_level, - "LOG_LEVEL_WARNING", - "The lowest level of log messages to be copied to stderr in addition to log files"); -DSN_DEFINE_validator(stderr_start_level, [](const char *value) -> bool { - const auto level = enum_from_string(value, LOG_LEVEL_INVALID); - return LOG_LEVEL_DEBUG <= level && level <= LOG_LEVEL_FATAL; -}); - DSN_DECLARE_string(logging_start_level); namespace dsn { namespace tools { simple_logger::simple_logger(const char *log_dir, const char *role_name) - : logging_provider(enum_from_string(FLAGS_stderr_start_level, LOG_LEVEL_INVALID)) { // TODO(yingchun): simple_logger is destroyed after command_manager, so will cause crash like // "assertion expression: [_handlers.empty()] All commands must be deregistered before @@ -82,8 +71,8 @@ simple_logger::simple_logger(const char *log_dir, const char *role_name) "flush-log", "Flush log to stderr or file", "", - [this](const std::vector &args) { - this->flush(); + [](const std::vector &args) { +// this->flush(); return "Flush done."; })); diff --git a/src/utils/simple_logger.h b/src/utils/simple_logger.h index 9d7e7798d9..2f662d10f1 100644 --- a/src/utils/simple_logger.h +++ b/src/utils/simple_logger.h @@ -42,12 +42,14 @@ namespace tools { * simple_logger provides a logger which writes to file. * The max number of lines in a logger file is 200000. */ -class simple_logger : public logging_provider +class simple_logger { public: // 'log_dir' is the directory to store log files, 'role_name' is the name of the process, // such as 'replica_server', 'meta_server' in Pegasus. simple_logger(const char *log_dir, const char *role_name); + + std::vector> _cmds; }; } // namespace tools } // namespace dsn diff --git a/src/utils/test/logger.cpp b/src/utils/test/logger.cpp index 8b73cac28b..e4caa4ebba 100644 --- a/src/utils/test/logger.cpp +++ b/src/utils/test/logger.cpp @@ -48,12 +48,6 @@ namespace dsn { namespace tools { class logger_test : public testing::Test { -public: - void SetUp() override - { - // Deregister commands to avoid re-register error. - dsn::logging_provider::instance()->deregister_commands(); - } }; class simple_logger_test : public logger_test