本文介绍使用spdlog的入门教程,包括下载、安装、编译和简单的测试用例。
0x01 下载
我们在spdlog的官网下载库文件,本文以V1.17.0版本示例,链接如下:
https://github.com/gabime/spdlog
https://github.com/gabime/spdlog/archive/refs/tags/v1.17.0.tar.gz
spdlog可以编译为动态库或者静态库,也可以直接包含头文件。为方便演示,本文示例代码直接引用头文件。
下载完毕后,将spdlog-1.17.0.tar.gz解压,解压后如下图所示:

我们仅需include文件夹,除该文件夹之外的其他可以全部删除。
0x02 使用CMake编译测试代码
以下是我们测试异步日志的代码:
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
| #include <iostream>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/async.h>
#include <spdlog/fmt/ostr.h>
#define SPDLOG_LOG_TRACE(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::trace, __VA_ARGS__)
#define SPDLOG_LOG_DEBUG(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::debug, __VA_ARGS__)
#define SPDLOG_LOG_INFO(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::info, __VA_ARGS__)
#define SPDLOG_LOG_WARN(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::warn, __VA_ARGS__)
#define SPDLOG_LOG_ERROR(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::err, __VA_ARGS__)
#define SPDLOG_LOG_CRITI(loggerName, ...) SPDLOG_LOGGER_CALL(spdlog::get(loggerName), spdlog::level::critical, __VA_ARGS__)
#define LOG_ERROR(...) SPDLOG_LOG_ERROR("async_logger", __VA_ARGS__)
int test_case_6()
{
std::cout << "test_case_6" << std::endl << std::endl;
try
{
spdlog::flush_every(std::chrono::seconds(1)); // 定时刷新
spdlog::init_thread_pool(8192, 1); // 队列大小8192,后台线程数1
std::shared_ptr<spdlog::sinks::basic_file_sink_mt> async_file_sink =
std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/test_case_6.txt");
std::shared_ptr<spdlog::async_logger> async_logger =
std::make_shared<spdlog::async_logger>(
"async_logger",
async_file_sink,
spdlog::thread_pool(),
spdlog::async_overflow_policy::block
);
spdlog::register_logger(async_logger);
async_logger->info("异步日志测试: 高并发场景推荐使用|Test>1");
async_logger->set_level(spdlog::level::err);
async_logger->info("异步日志测试: 高并发场景推荐使用|Test>2");
async_logger->error("异步日志测试: 高并发场景推荐使用|Test>3");
SPDLOG_LOG_INFO("async_logger", "SPDLOG_LOG_INFO TEST");
LOG_ERROR("LOG_ERROR TEST");
getchar();
spdlog::shutdown(); // 程序结束前必须调用,确保所有日志写入磁盘
}
catch (const spdlog::spdlog_ex& ex)
{
std::cerr << "spdlog初始化失败: " << ex.what() << std::endl;
return 1;
}
return 0;
}
|
以下是我们编译测试代码的CMakeLists.txt文件内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| SET(app_name demo)
CMAKE_MINIMUM_REQUIRED(VERSION 3.21 FATAL_ERROR)
PROJECT(${app_name} LANGUAGES CXX)
if(MSVC)
ADD_COMPILE_OPTIONS("/utf-8")
endif()
ADD_EXECUTABLE(${app_name}
main.cpp
test_case_1.cpp
test_case_2.cpp
test_case_3.cpp
test_case_4.cpp
test_case_5.cpp
test_case_6.cpp)
TARGET_INCLUDE_DIRECTORIES(${app_name} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../spdlog-1.17.0/include")
|
使用如下命令编译:
1
2
3
| cmake -S . -B build -A x64
cmake --build build --config Release
|
编译过程如下图所示:

编译成功后,在build/Release目录下可见 demo.exe,运行该程序,生成日志文件 logs/test_case_6.txt ,如下图所示:

0x03 使用Visual Code编译测试代码
使用Visual Code编译上述代码测试代码,需设置附加包含目录,将其定位到spdlog-1.17.0.tar.gz解压后include文件夹的路径,如下图所示:

按上述方法设置附加包含目录后,即可正常编译。
问题:C2338 Unicode support requires compiling with /utf-8
在使用Visual Studio编译测试代码时,会报C2338错误,错误信息如下图所示:
1
| 错误 C2338 Unicode support requires compiling with /utf-8
|

这是MSVC编译器的静态断言错误,核心原因是:代码中使用了依赖UTF-8编码的Unicode特性,但当前编译环境未启用UTF-8支持。
MSVC默认使用系统本地编码(如Windows上的GB2312/GBK),而现代C++库(如fmt、spdlog)为了跨平台一致性,要求必须用UTF-8编码编译。当库检测到当前环境不符合要求时,会触发static_assert终止编译。

从断言的定义出发,解决该错误报警一般有如下两种方法:
第一种,在引入spdlog的头文件之前,定义不支持UNICODE,即:FMT_UNICODE == 0,实现方法如下图所示:
1
| #define FMT_UNICODE 0 // 在include spdlog头文件之前进行定义
|

第二种,设置Visual Studio按UTF-8编译。
操作步骤是,右键项目 → 属性 → 配置属性 → C/C++ → 命令行 → 其他选项,然后添加/utf-8。如下图所示:

使用如上两种方法,均可编译成功。如当前使用的是cmake编译,增加编译选项ADD_COMPILE_OPTIONS("/utf-8"),如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| SET(app_name demo)
CMAKE_MINIMUM_REQUIRED(VERSION 3.21 FATAL_ERROR)
PROJECT(${app_name} LANGUAGES CXX)
if(MSVC)
ADD_COMPILE_OPTIONS("/utf-8")
endif()
ADD_EXECUTABLE(${app_name}
main.cpp
test_case_1.cpp
test_case_2.cpp
test_case_3.cpp
test_case_4.cpp
test_case_5.cpp
test_case_6.cpp)
TARGET_INCLUDE_DIRECTORIES(${app_name} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../spdlog-1.17.0/include")
|