spdlog sinks
时间: 2023-09-01 18:09:20 浏览: 50
spdlog是一个C++的快速、异步、多线程安全的日志库,它提供了多种不同的sinks(输出目标)用于日志的输出。
sinks是spdlog中用于指定日志输出目标的组件。它们决定了日志消息将被发送到哪里,比如控制台、文件、网络等。spdlog提供了多种不同的sinks,以满足不同的需求。
以下是spdlog支持的一些常见sinks:
1. stdout_sink_st:将日志消息输出到标准输出(控制台)。
2. basic_file_sink_st:将日志消息输出到文件。
3. rotating_file_sink_st:将日志消息输出到循环文件中,当文件大小达到设定的阈值时自动切换到下一个文件。
4. daily_file_sink_st:将日志消息输出到每天一个新文件的循环文件中。
5. null_sink_st:空sink,不进行任何输出。
你可以根据自己的需求选择适合的sink,并通过spdlog配置日志库的输出目标。
相关问题
spdlog 使用教程
spdlog 是一个快速的 C++ 日志库,支持多线程、异步日志等功能。以下是 spdlog 的使用教程:
1. 安装 spdlog
spdlog 可以通过包管理器或源码编译安装。具体安装方式请参考官方文档。
2. 创建 logger
使用 spdlog,首先需要创建一个 logger 对象。logger 对象用于记录日志,并可以设置日志级别、输出格式等属性。
```c++
#include "spdlog/spdlog.h"
auto logger = spdlog::basic_logger_mt("logger_name", "log_file_path");
```
上面的代码创建了一个名为 "logger_name" 的 logger 对象,并将日志输出到指定的文件中。如果日志文件不存在,则会自动创建。
3. 记录日志
使用 logger 对象记录日志非常简单,只需要调用对应的函数即可。
```c++
logger->trace("trace message");
logger->debug("debug message");
logger->info("info message");
logger->warn("warn message");
logger->error("error message");
logger->critical("critical message");
```
上面的代码分别记录了 trace、debug、info、warn、error 和 critical 级别的日志。
4. 设置日志级别
日志级别用于控制日志的输出,只有大于等于指定级别的日志才会被输出。默认情况下,spdlog 的日志级别为 debug。
```c++
logger->set_level(spdlog::level::info);
```
上面的代码将日志级别设置为 info,只有 info、warn、error 和 critical 级别的日志才会被输出。
5. 设置日志输出格式
可以通过设置日志输出格式,控制日志的显示方式。
```c++
auto formatter = spdlog::pattern_formatter("[%Y-%m-%d %H:%M:%S.%e] [%L] %v");
logger->set_formatter(formatter);
```
上面的代码设置了一个输出格式,包含时间、日志级别和日志内容。
6. 多线程和异步日志
spdlog 支持多线程和异步日志,可以提高日志记录的效率。
```c++
auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("log.txt", true);
std::vector<spdlog::sink_ptr> sinks = {console_sink, file_sink};
auto logger = std::make_shared<spdlog::logger>("logger_name", begin(sinks), end(sinks));
logger->set_level(spdlog::level::trace);
logger->flush_on(spdlog::level::info);
spdlog::set_default_logger(logger);
spdlog::register_logger(logger);
spdlog::flush_every(std::chrono::seconds(3));
logger->trace("trace message");
logger->debug("debug message");
logger->info("info message");
logger->warn("warn message");
logger->error("error message");
logger->critical("critical message");
```
上面的代码创建了两个输出端,一个是控制台,一个是文件,然后将它们绑定到 logger 对象中。设置了日志级别为 trace,并且在输出 info 级别的日志时立即刷新缓存。最后设置了定时刷新缓存的时间间隔为 3 秒。
7. 总结
以上就是 spdlog 的使用教程,通过设置 logger 对象的属性,可以灵活地控制日志的输出方式。spdlog 支持多线程和异步日志,可以提高日志记录的效率。
#ifndef MYSPDLOG_H #define MYSPDLOG_H #include <fstream> #include <iostream> #define SPDLOG_HEADER_ONLY #define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG #include "spdlog/spdlog.h" #include "spdlog/logger.h" #include "spdlog/sinks/basic_file_sink.h" #include "spdlog/sinks/rotating_file_sink.h" #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/daily_file_sink.h" class MySpdlog { public: static MySpdlog*getInstace() { static MySpdlog MySpdlogStatic; return &MySpdlogStatic; } int init() { std::string formatStr="%Y-%m-%dT%H:%M:%S.%e[%l][%s:%#][%!]%v"; // auto myLogger1 = std::make_shared<spdlog::sinks::rotating_file_sink_mt>("spdlog", "logs/myspdlog.log", 1024 * 1024 * 10, 10); // auto myLogger1 = std::make_shared<spdlog::sinks::daily_file_sink>("spdlog", "logs/log.txt", 0, 0); auto myLogger1 = spdlog::daily_logger_mt("spdlog", "logs/log.txt", 0, 0); // myLogger1 = spdlog::rotating_logger_mt("spdlog", "logs/myspdlog.log", 1024 * 1024 * 10, 10); spdlog::set_default_logger(myLogger1); myLogger1->set_level(spdlog::level::debug); myLogger1->set_pattern(formatStr); myLogger2 = spdlog::stdout_color_mt("baseLogger2"); spdlog::set_default_logger(myLogger2); myLogger2->set_level(spdlog::level::debug); myLogger2->set_pattern(formatStr); return 0; } void uninit() { } std::shared_ptr<spdlog::logger> myLogger1; std::shared_ptr<spdlog::logger> myLogger2; private: MySpdlog() {} ~MySpdlog() {} }; #define SPLOG_INIT() MySpdlog::getInstace()->init() #define SPLOG_UNINIT() MySpdlog::getInstace()->uninit() #define SPLOG_DEBUG(...) do {SPDLOG_LOGGER_DEBUG(MySpdlog::getInstace()->myLogger1, __VA_ARGS__);\ SPDLOG_LOGGER_DEBUG(MySpdlog::getInstace()->myLogger2, __VA_ARGS__);}while(0) #define SPLOG_INFO(...) do {SPDLOG_LOGGER_INFO(MySpdlog::getInstace()->myLogger1, __VA_ARGS__);\ SPDLOG_LOGGER_INFO(MySpdlog::getInstace()->myLogger2, __VA_ARGS__);}while(0) #define SPLOG_ERROR(...) do {SPDLOG_LOGGER_ERROR(MySpdlog::getInstace()->myLogger1, __VA_ARGS__);\ SPDLOG_LOGGER_ERROR(MySpdlog::getInstace()->myLogger2, __VA_ARGS__);}while(0) #define SPDLOG_CLRAR(a) do{std::fstream fout((a),std::ios::out|std::ios::trunc);fout.close();}while(0); #endif // MYSPDLOG_H运行之后调用SPLOG_INFO时报错
根据您提供的代码,我看到您定义了一个名为`SPLOG_INFO`的宏,其实现方式为:
```
#define SPLOG_INFO(...) do {SPDLOG_LOGGER_INFO(MySpdlog::getInstace()->myLogger1, __VA_ARGS__);\
SPDLOG_LOGGER_INFO(MySpdlog::getInstace()->myLogger2, __VA_ARGS__);}while(0)
```
这个宏展开后会调用`SPDLOG_LOGGER_INFO`来输出日志信息,而`SPDLOG_LOGGER_INFO`需要传入一个有效的logger对象作为第一个参数。在您的代码中,您定义了一个名为`myLogger1`的logger对象,但是您没有在宏中使用它,而是在`MySpdlog`类中以成员变量的形式定义。因此,当您调用`SPLOG_INFO`时,会找不到有效的logger对象,从而导致编译错误。
要解决这个问题,您可以将`myLogger1`和`myLogger2`定义为静态成员变量,并在`MySpdlog`类外初始化它们。然后,在宏中使用这两个静态成员变量。
例如,您可以将`MySpdlog`类的定义改为:
```
class MySpdlog {
public:
static MySpdlog*getInstace()
{
static MySpdlog MySpdlogStatic;
return &MySpdlogStatic;
}
int init()
{
std::string formatStr="%Y-%m-%dT%H:%M:%S.%e[%l][%s:%#][%!]%v";
auto myLogger1 = spdlog::daily_logger_mt("spdlog", "logs/log.txt", 0, 0);
spdlog::set_default_logger(myLogger1);
myLogger1->set_level(spdlog::level::debug);
myLogger1->set_pattern(formatStr);
auto myLogger2 = spdlog::stdout_color_mt("baseLogger2");
spdlog::set_default_logger(myLogger2);
myLogger2->set_level(spdlog::level::debug);
myLogger2->set_pattern(formatStr);
return 0;
}
void uninit()
{
}
static std::shared_ptr<spdlog::logger> myLogger1;
static std::shared_ptr<spdlog::logger> myLogger2;
private:
MySpdlog() {}
~MySpdlog() {}
};
std::shared_ptr<spdlog::logger> MySpdlog::myLogger1;
std::shared_ptr<spdlog::logger> MySpdlog::myLogger2;
```
然后,您可以在代码的其他地方使用这两个静态成员变量。例如,在`SPLOG_INFO`中,您可以这样使用:
```
#define SPLOG_INFO(...) \
do { \
SPDLOG_LOGGER_INFO(MySpdlog::myLogger1, __VA_ARGS__); \
SPDLOG_LOGGER_INFO(MySpdlog::myLogger2, __VA_ARGS__); \
} while(0)
```
这样,当您调用`SPLOG_INFO`时,就会使用正确的logger对象输出日志信息,从而避免编译错误。