封装 spdlog
spdlog 是一个快速、可扩展的 c++ 日志库,它提供了简单易用的接口和灵活的配置选项。spdlog 支持多种日志级别、多线程安全,可以将日志输出到终端、文件或者其他自定义的目标。它具有高性能和低开销的特点,适用于各种规模的应用程序和系统。
获取源码
如果要将源码添加进你的工程里,请从 github 获取
1
https://github.com/gabime/spdlog
- 如果使用的是 conan 包管理,可以从这里获取
1
https://conan.io/center/recipes/spdlog
封装 spdlog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// 单例模板
#include <iostream>
#include <string>
template<class T>
class Singleton
{
protected:
Singleton(const Singleton &) = delete;
Singleton &operator=(const Singleton &) = delete;
Singleton() = default;
~Singleton() = default;
public:
template<typename... Args>
static T &instance(Args &&...args)
{
static T obj(std::forward<Args>(args)...);
return obj;
}
};
// spdlog wraper
#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h"
#include <memory>
#define LOG_TOPIC "app" // 日志tag
#define LOG_FILE_NAME "./log/" LOG_TOPIC ".log" // 日志文件名
#define LOG_FILE_SIZE 1024 * 1024 * 3 // 3MB
#define LOG_ROTATION 3 // 日志文件满3个时开始滚动日志
#define PATTERN "[%Y-%m-%d %H:%M:%S.%f] [%^%L%$] %v" // 日志格式
#define LOG_FLUSH_ON spdlog::level::info // 当打印这个级别日志时flush
#define LOGE(...) Singleton<Logger>::Instance().log_error(__VA_ARGS__)
#define LOGW(...) Singleton<Logger>::Instance().log_warn(__VA_ARGS__)
#define LOGI(...) Singleton<Logger>::Instance().log_info(__VA_ARGS__)
#define LOGD(...) Singleton<Logger>::Instance().log_debug(__VA_ARGS__)
#define LOGC(...) Singleton<Logger>::Instance().log_critical(__VA_ARGS__)
class Logger
{
private:
std::unique_ptr<spdlog::logger> logger_;
public:
Logger()
{
auto function = [&]() {
auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto rotating_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(LOG_FILE_NAME, LOG_FILE_SIZE, LOG_ROTATION);
std::vector<spdlog::sink_ptr> sinks{stdout_sink, rotating_sink};
logger_ = std::make_unique<spdlog::logger>(LOG_TOPIC, sinks.begin(), sinks.end());
logger_->set_pattern(PATTERN);
if (is_debug_mode())
{
logger_->set_level(spdlog::level::debug);
}
else
{
logger_->set_level(spdlog::level::info);
}
logger_->flush_on(LOG_FLUSH_ON);
};
try
{
function();
} catch (...)
{
std::cout << "init failed" << std::endl;
}
}
template<typename... Args>
inline void log_error(const char *fmt, Args... args)
{
logger_->error(fmt, args...);
}
template<typename... Args>
inline void log_warn(const char *fmt, Args... args)
{
logger_->warn(fmt, args...);
}
template<typename... Args>
inline void log_info(const char *fmt, Args... args)
{
logger_->info(fmt, args...);
}
template<typename... Args>
inline void log_debug(const char *fmt, Args... args)
{
logger_->debug(fmt, args...);
}
template<typename... Args>
inline void log_critical(const char *fmt, Args... args)
{
logger_->critical(fmt, args...);
}
private:
bool is_debug_mode()
{
char *var = getenv("debug");
if (nullptr == var)
{
return false;
}
if (0 == strcmp(var, "on"))
{
return true;
}
return false;
}
};
本文由作者按照 CC BY 4.0 进行授权