Skip to content

Commit

Permalink
优化logger
Browse files Browse the repository at this point in the history
  • Loading branch information
fasiondog committed Aug 2, 2024
1 parent a9af07f commit 54ecb2d
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 200 deletions.
1 change: 0 additions & 1 deletion config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ ${define HKU_ENABLE_STACK_TRACE}

${define HKU_CLOSE_SPEND_TIME}

${define HKU_DEFAULT_LOG_NAME}
${define HKU_USE_SPDLOG_ASYNC_LOGGER}
${define HKU_LOG_ACTIVE_LEVEL}

Expand Down
116 changes: 19 additions & 97 deletions hikyuu/utilities/Log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "os.h"
#include "Log.h"

#if USE_SPDLOG_LOGGER
// 使用 stdout_color 将无法将日志输出重定向至 python
#include <spdlog/sinks/stdout_color_sinks.h>
#include <iostream>
Expand All @@ -19,11 +18,6 @@
#if HKU_USE_SPDLOG_ASYNC_LOGGER
#include <spdlog/async.h>
#endif /* HKU_USE_SPDLOG_ASYNC_LOGGER */
#endif /* #if USE_SPDLOG_LOGGER */

#ifndef HKU_DEFAULT_LOG_NAME
#define HKU_DEFAULT_LOG_NAME "hikyuu"
#endif

namespace hku {

Expand All @@ -35,88 +29,51 @@ LOG_LEVEL get_log_level() {
return g_log_level;
}

/**********************************************
* Use SPDLOG for logging
*********************************************/
#if USE_SPDLOG_LOGGER
void set_log_level(LOG_LEVEL level) {
g_log_level = level;
getHikyuuLogger()->set_level((spdlog::level::level_enum)level);
}

std::shared_ptr<spdlog::logger> getHikyuuLogger() {
return spdlog::get(HKU_DEFAULT_LOG_NAME);
auto logger = spdlog::get("hikyuu");
return logger ? logger : spdlog::default_logger();
}

#if HKU_USE_SPDLOG_ASYNC_LOGGER
void HKU_UTILS_API initLogger(bool inJupyter) {
std::string logname(HKU_DEFAULT_LOG_NAME);
void HKU_UTILS_API initLogger(bool not_use_color, const std::string& filename) {
std::string logname("hikyuu");
spdlog::drop(logname);
std::shared_ptr<spdlog::logger> logger = spdlog::get(logname);
if (logger) {
spdlog::drop(logname);
}

spdlog::sink_ptr stdout_sink;
if (inJupyter) {
if (not_use_color) {
stdout_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(std::cout, true);
} else {
stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
}
stdout_sink->set_level(spdlog::level::trace);

std::shared_ptr<spdlog::sinks::rotating_file_sink_mt> rotating_sink;
if (createDir(fmt::format("{}/.hikyuu", getUserDir()))) {
std::string log_filename =
fmt::format("{}/.hikyuu/{}.log", getUserDir(), HKU_DEFAULT_LOG_NAME);
rotating_sink =
std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_filename, 1024 * 1024 * 10, 3);
rotating_sink->set_level(spdlog::level::warn);
}
std::string logfile = filename.empty() ? "./hikyuu.log" : filename;
auto rotating_sink =
std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logfile, 1024 * 1024 * 10, 3);
rotating_sink->set_level(spdlog::level::warn);

std::vector<spdlog::sink_ptr> sinks{stdout_sink};
if (rotating_sink) {
sinks.emplace_back(rotating_sink);
}

#if HKU_USE_SPDLOG_ASYNC_LOGGER
spdlog::init_thread_pool(8192, 1);
logger = std::make_shared<spdlog::async_logger>(logname, sinks.begin(), sinks.end(),
spdlog::thread_pool(),
spdlog::async_overflow_policy::block);

logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::trace);
logger->set_pattern("%Y-%m-%d %H:%M:%S.%e [%^HKU-%L%$] - %v [%!]");
// logger->set_pattern("%^%Y-%m-%d %H:%M:%S.%e [HKU-%L] - %v (%s:%#)%$");
// spdlog::register_logger(logger);
spdlog::set_default_logger(logger);
}

#else /* #if HKU_USE_SPDLOG_ASYNC_LOGGER */

void HKU_UTILS_API initLogger(bool inJupyter) {
std::string logname(HKU_DEFAULT_LOG_NAME);
spdlog::drop(logname);
std::shared_ptr<spdlog::logger> logger = spdlog::get(logname);
if (logger) {
spdlog::drop(logname);
}
spdlog::sink_ptr stdout_sink;
if (inJupyter) {
stdout_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(std::cout, true);
} else {
stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
}
stdout_sink->set_level(spdlog::level::trace);

std::shared_ptr<spdlog::sinks::rotating_file_sink_mt> rotating_sink;
if (createDir(fmt::format("{}/.hikyuu", getUserDir()))) {
std::string log_filename =
fmt::format("{}/.hikyuu/{}.log", getUserDir(), HKU_DEFAULT_LOG_NAME);
rotating_sink =
std::make_shared<spdlog::sinks::rotating_file_sink_mt>(log_filename, 1024 * 1024 * 10, 3);
rotating_sink->set_level(spdlog::level::warn);
}

std::vector<spdlog::sink_ptr> sinks{stdout_sink};
if (rotating_sink) {
sinks.emplace_back(rotating_sink);
}
#else
logger = std::make_shared<spdlog::logger>(logname, sinks.begin(), sinks.end());
#endif

logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::trace);
logger->set_pattern("%Y-%m-%d %H:%M:%S.%e [%^HKU-%L%$] - %v (%s:%#)");
Expand All @@ -125,39 +82,4 @@ void HKU_UTILS_API initLogger(bool inJupyter) {
spdlog::set_default_logger(logger);
}

#endif /* #if HKU_USE_SPDLOG_ASYNC_LOGGER */

void set_log_level(LOG_LEVEL level) {
g_log_level = level;
getHikyuuLogger()->set_level((spdlog::level::level_enum)level);
}

#else /* #if USE_SPDLOG_LOGGER */
/**********************************************
* Use SPDLOG for logging
*********************************************/
void HKU_UTILS_API initLogger(bool inJupyter) {}

void set_log_level(LOG_LEVEL level) {
g_log_level = level;
}

std::string HKU_UTILS_API getLocalTime() {
auto now = std::chrono::system_clock::now();
uint64_t dis_millseconds =
std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()).count() -
std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count() * 1000;
time_t tt = std::chrono::system_clock::to_time_t(now);
#ifdef _WIN32
struct tm now_time;
localtime_s(&now_time, &tt);
#else
struct tm now_time;
localtime_r(&tt, &now_time);
#endif
return fmt::format("{:%Y-%m-%d %H:%M:%S}.{:<3d}", now_time, dis_millseconds);
}

#endif /* #if USE_SPDLOG_LOGGER */

} // namespace hku
97 changes: 16 additions & 81 deletions hikyuu/utilities/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,15 @@
#define HKU_LOG_ACTIVE_LEVEL 0
#endif

#if !defined(USE_SPDLOG_LOGGER)
#define USE_SPDLOG_LOGGER 1
// clang-format off
#ifndef SPDLOG_ACTIVE_LEVEL
#define SPDLOG_ACTIVE_LEVEL HKU_LOG_ACTIVE_LEVEL
#endif

// clang-format off
#if USE_SPDLOG_LOGGER
#define SPDLOG_ACTIVE_LEVEL HKU_LOG_ACTIVE_LEVEL
#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#if HKU_USE_SPDLOG_ASYNC_LOGGER
#include "spdlog/async.h"
#endif
#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#if HKU_USE_SPDLOG_ASYNC_LOGGER
#include "spdlog/async.h"
#endif
// clang-format on

Expand All @@ -56,7 +53,7 @@ namespace hku {
/**********************************************
* Use SPDLOG for logging
*********************************************/
#if USE_SPDLOG_LOGGER

/** 日志级别 */
enum LOG_LEVEL {
LOG_TRACE = SPDLOG_LEVEL_TRACE, ///< 跟踪
Expand All @@ -68,6 +65,14 @@ enum LOG_LEVEL {
LOG_OFF = SPDLOG_LEVEL_OFF, ///< 关闭日志打印
};

/**
* 初始化 logger
* @param not_use_color 不使用彩色输出
* @param filename 日志文件名,为空时默认为当前目录下 "./hikyuu.log",需自行保存存放目录存在且可写入
*/
void HKU_UTILS_API initLogger(bool not_use_color = false,
const std::string& filename = std::string());

/**
* 获取当前日志级别
* @return
Expand All @@ -89,76 +94,6 @@ std::shared_ptr<spdlog::logger> HKU_UTILS_API getHikyuuLogger();
#define HKU_ERROR(...) SPDLOG_LOGGER_ERROR(hku::getHikyuuLogger(), __VA_ARGS__)
#define HKU_FATAL(...) SPDLOG_LOGGER_CRITICAL(hku::getHikyuuLogger(), __VA_ARGS__)

void HKU_UTILS_API initLogger(bool inJupyter = false);

#else
enum LOG_LEVEL {
LOG_TRACE = 0,
LOG_DEBUG = 1,
LOG_INFO = 2,
LOG_WARN = 3,
LOG_ERROR = 4,
LOG_FATAL = 5,
LOG_OFF = 6,
};

LOG_LEVEL HKU_UTILS_API get_log_level();
void HKU_UTILS_API set_log_level(LOG_LEVEL level);
void HKU_UTILS_API initLogger(bool inJupyter = false);

/** 获取系统当前时间,精确到毫秒,如:2001-01-02 13:01:02.001 */
std::string HKU_UTILS_API getLocalTime();

#if HKU_LOG_ACTIVE_LEVEL <= 0
#define HKU_TRACE(...) \
fmt::print("[{}] [HKU-T] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_TRACE(...)
#endif

#if HKU_LOG_ACTIVE_LEVEL <= 1
#define HKU_DEBUG(...) \
fmt::print("[{}] [HKU-D] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_DEBUG(...)
#endif

#if HKU_LOG_ACTIVE_LEVEL <= 2
#define HKU_INFO(...) \
fmt::print("[{}] [HKU-I] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_INFO(...)
#endif

#if HKU_LOG_ACTIVE_LEVEL <= 3
#define HKU_WARN(...) \
fmt::print("[{}] [HKU-W] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_WARN(...)
#endif

#if HKU_LOG_ACTIVE_LEVEL <= 4
#define HKU_ERROR(...) \
fmt::print("[{}] [HKU-E] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_ERROR(...)
#endif

#if HKU_LOG_ACTIVE_LEVEL <= 5
#define HKU_FATAL(...) \
fmt::print("[{}] [HKU-F] - {} ({}:{})\n", getLocalTime(), fmt::format(__VA_ARGS__), __FILE__, \
__LINE__);
#else
#define HKU_FATAL(...)
#endif

#endif /* USE_SPDLOG_LOGGER */

///////////////////////////////////////////////////////////////////////////////
//
// clang/gcc 下使用 __PRETTY_FUNCTION__ 会包含函数参数,可以在编译时指定
Expand Down
2 changes: 2 additions & 0 deletions test/test_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ int main(int argc, char** argv) {
// overrides
context.setOption("no-breaks", true); // don't break in the debugger when assertions fail

HKU_INFO("before init log");

hku::initLogger();

HKU_INFO("current utils version: {}", hku::utils::getVersion());
Expand Down
34 changes: 13 additions & 21 deletions xmake.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ set_warnings("all", "error")

add_rules("mode.debug", "mode.release", "mode.coverage", "mode.profile")

set_objectdir("$(buildir)/$(mode)/$(plat)/$(arch)/.objs")
set_targetdir("$(buildir)/$(mode)/$(plat)/$(arch)/lib")

option("mysql")
set_default(false)
set_showmenu(true)
Expand Down Expand Up @@ -47,8 +50,7 @@ option("stacktrace", {description = "Enable check/assert with stack trace info."
option("datetime", {description = "Enable DateTime.", default = true})
option("spend_time", {description = "Enable spent time.", default = true})

option("log_name", {description = "set default log name.", default = "hikyuu"})
option("log_level", {description = "set log level.", default = "info", values = {"trace", "debug", "info", "warn", "error", "fatal", "off"}})
option("log_level", {description = "set log level.", default = 2, values = {1, 2, 3, 4, 5, 6}})
option("async_log", {description = "Use async log.", default = false})

option("leak_check", {description = "Enable leak check for test", default = false})
Expand All @@ -67,6 +69,13 @@ if has_config("leak_check") then
-- set_policy("build.sanitizer.thread", true)
end

-- SPDLOG_ACTIVE_LEVEL 需要单独加
local log_level = get_config("log_level")
if log_level == nil then
log_level = 2
end
add_defines("SPDLOG_ACTIVE_LEVEL=" .. log_level)

-- is release now
if is_mode("release") then
if is_plat("windows") then
Expand Down Expand Up @@ -161,8 +170,7 @@ if has_config("http_client") or has_config("node") then
end
end

set_objectdir("$(buildir)/$(mode)/$(plat)/$(arch)/.objs")
set_targetdir("$(buildir)/$(mode)/$(plat)/$(arch)/lib")


target("hku_utils")
set_kind("$(kind)")
Expand All @@ -185,24 +193,8 @@ target("hku_utils")
set_configvar("HKU_ENABLE_HTTP_CLIENT_ZIP", has_config("http_client_zip") and 1 or 0)
set_configvar("HKU_ENABLE_NODE", has_config("node") and 1 or 0)

set_configvar("HKU_DEFAULT_LOG_NAME", get_config("log_name"))
set_configvar("HKU_USE_SPDLOG_ASYNC_LOGGER", has_config("async_log") and 1 or 0)
local level = get_config("log_level")
if level == "trace" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 0)
elseif level == "debug" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 1)
elseif level == "info" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 2)
elseif level == "warn" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 3)
elseif level == "error" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 4)
elseif level == "fatal" then
set_configvar("HKU_LOG_ACTIVE_LEVEL", 5)
else
set_configvar("HKU_LOG_ACTIVE_LEVEL", 6)
end
set_configvar("HKU_LOG_ACTIVE_LEVEL", get_config("log_level"))

add_packages("fmt", "spdlog", "boost", "yas")

Expand Down

0 comments on commit 54ecb2d

Please sign in to comment.