1
2
3
4
5
6
#include "spdlog/spdlog.h"
int main()
{
//Use the default logger (stdout, multi-threaded, colored)
spdlog::info("Hello, {}!", "World");
}

spdlog 是一个仅有头文件的库。只需将 include下的文件复制到您的项目中并使用 C++11 编译器即可。

它使用了fmt库提供了类似 Python 的格式化 API (参见参考):

1
logger->info("Hello {} {} !!", "param1", 123.4);

spdlog 采用“包含您需要的内容”方法 - 您的代码应该包含实际需要的功能。

例如,如果您只需要旋转记录器,则需要包含“ spdlog/sinks/rotating_file_sink.h ”。

另一个示例是包含“ spdlog/async.h ”以获取异步日志记录功能。

基本示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h" // support for basic file logging
#include "spdlog/sinks/rotating_file_sink.h" // support for rotating file logging

int main(int, char* [])
{
try
{
// Create basic file logger (not rotated)
auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic.txt");

// create a file rotating logger with 5mb size max and 3 rotated files
auto file_logger = spdlog::rotating_logger_mt("file_logger", "myfilename", 1024 * 1024 * 5, 3);
}
catch (const spdlog::spdlog_ex& ex)
{
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}

使用工厂方法创建异步记录器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/async.h" //support for async logging.
#include "spdlog/sinks/basic_file_sink.h"

int main(int, char* [])
{
try
{
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
for (int i = 1; i < 101; ++i)
{
async_file->info("Async message #{}", i);
}
// Under VisualStudio, this must be called before main finishes to workaround a known VS issue
spdlog::drop_all();
}
catch (const spdlog::spdlog_ex& ex)
{
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}

创建异步记录器并更改线程池设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "spdlog/async.h" //support for async logging
#include "spdlog/sinks/daily_file_sink.h"
int main(int, char* [])
{
try
{
auto daily_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>("logfile", 23, 59);
// default thread pool settings can be modified *before* creating the async logger:
spdlog::init_thread_pool(10000, 1); // queue with 10K items and 1 backing thread.
auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");
spdlog::drop_all();
}
catch (const spdlog::spdlog_ex& ex)
{
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}

创建共享同一文件(接收器)又称类别的多个记录器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/daily_file_sink.h"
int main(int, char* [])
{
try
{
auto daily_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>("logfile", 23, 59);
// create synchronous loggers
auto net_logger = std::make_shared<spdlog::logger>("net", daily_sink);
auto hw_logger = std::make_shared<spdlog::logger>("hw", daily_sink);
auto db_logger = std::make_shared<spdlog::logger>("db", daily_sink);

net_logger->set_level(spdlog::level::critical); // independent levels
hw_logger->set_level(spdlog::level::debug);

// globally register the loggers so they can be accessed using spdlog::get(logger_name)
spdlog::register_logger(net_logger);
}
catch (const spdlog::spdlog_ex& ex)
{
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}

创建一个具有多个接收器的记录器,每个接收器都有自己的格式和日志级别

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
//
// Logger with console and file output.
// the console will show only warnings or worse, while the file will log all messages.
//
#include <iostream>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h" // or "../stdout_sinks.h" if no colors needed
#include "spdlog/sinks/basic_file_sink.h"
int main(int, char* [])
{
try
{
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_level(spdlog::level::warn);
console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");

auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", true);
file_sink->set_level(spdlog::level::trace);

spdlog::sinks_init_list sink_list = { file_sink, console_sink };

spdlog::logger logger("multi_sink", sink_list.begin(), sink_list.end());
logger.set_level(spdlog::level::debug);
logger.warn("this should appear in both console and file");
logger.info("this message should not appear in the console, only in the file");

// or you can even set multi_sink logger as default logger
spdlog::set_default_logger(std::make_shared<spdlog::logger>("multi_sink", spdlog::sinks_init_list({console_sink, file_sink})));

}
catch (const spdlog::spdlog_ex& ex)
{
std::cout << "Log initialization failed: " << ex.what() << std::endl;
}
}

记录宏

您可以在包含“spdlog.h”之前将 SPDLOG_ACTIVE_LEVEL 定义为所需的日志级别。

这将在编译时打开/关闭日志记录语句

1
2
3
4
5
6
7
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG

spdlog::set_level(spdlog::level::debug); // or spdlog::set_level(spdlog::level::trace);

SPDLOG_LOGGER_TRACE(file_logger , "Some trace message that will not be evaluated.{} ,{}", 1, 3.23);
SPDLOG_LOGGER_DEBUG(file_logger , "Some Debug message that will be evaluated.. {} ,{}", 1, 3.23);
SPDLOG_DEBUG("Some debug message to default logger that will be evaluated");

请注意,spdlog::set_level还需要打印出调试或跟踪消息。

记录用户定义对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h" // must be included
#include "spdlog/sinks/stdout_sinks.h"

class some_class {};
std::ostream& operator<<(std::ostream& os, const some_class& c)
{
return os << "some_class";
}

// fmt v10 and above requires `fmt::formatter<T>` extends `fmt::ostream_formatter`.
// See: https://github.com/fmtlib/fmt/issues/3318
template <> struct fmt::formatter<some_class> : fmt::ostream_formatter {};

void custom_class_example()
{
some_class c;
auto console = spdlog::stdout_logger_mt("console");
console->info("custom class with operator<<: {}..", c);
}

或者在需要高级格式化时使用捆绑的库:fmt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iterator>

#include "spdlog/spdlog.h"
#include "spdlog/fmt/ostr.h" // must be included
#include "spdlog/sinks/stdout_sinks.h"

class some_class {
int code;
};

template<typename OStream>
friend OStream &operator<<(OStream &os, const some_class& to_log)
{
fmt::format_to(std::ostream_iterator<char>(os), "{:04X}", to_log.code);
return os;
}

void custom_class_example()
{
some_class c; c.code = 17;
auto console = spdlog::stdout_logger_mt("console");
console->info("custom class with operator<< using fmt: {}..", c);
}

参考链接:https://github.com/gabime/spdlog/wiki/1.-QuickStart