本文主要是介绍日志记录库 spdlog 基础使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
基础介绍
spdlog是基于C++11实现的一款纯头文件的日志管理库(git地址:https://github.com/gabime/spdlog,API说明:https://spdlog.docsforge.com/v1.x/1.quickstart/):
- 配置特别简单,仅包含头文件即可;
- 写日志方式简单明了;
- 可实现自动按日期创建日志文件/定时创建日志文件;
- 可自定义日志格式;
- 可以输出当前输出日志所在的文件及函数;
- 可自定义文档大小;
- 可将不同级别的信息输出到不同日志文件;
- 多平台等。
spdlog中各对象都分为多线程与单线程版本:
- *_st:单线程版本,不用加锁,效率更高。
- *_mt:多线程版本,用于多线程程序是线程安全的。
日志记录槽sink
spdlog定义了几种sinks用于不同场景(也可自定义)下的日志输出,sink中主要包含:
- set_pattern(const std::string&):设置日志输出的内容格式。
- set_level(level_enum): 设置日志输出的最低等级。
- log(log_msg):由logger自动调用,外部不会主动调用。
日志记录器logger
一个logger对象中存储有多个sink,当调用logger的日志输出函数时,logger会调用自身存储的所有sink对象的log(log_msg) 函数进行输出。
logger中主要包括:输出格式pattern,通过set_pattern可设定日志格式,如set_pattern(“[%Y-%m-%d %H:%M:%S.%e]%l: %v”);
spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l [thread %t] [%@,%!] - %v");
pattern的flag如下所示:
flag meaning example
%v 日志内容 “my log test content”
%t 线程ID “123”
%P 进程ID “234”
%n 记录器Logger名 “basicLogger”
%l 日志级别 “debug”, “info”, etc
%L 日志级别简称 “D”, “I”, etc
%a 星期几(简称) “Thu”
%A 星期几 “Thursday”
%b 月份简称 “Aug”
%B 月份 “August”
%c 日期时间 “Thu Aug 23 15:35:46 2014”
%C 年(两位) “14”
%Y 年 “2014”
%D %x 日期简写 “08/23/14”
%m 月份(数字) “11”
%d 日(数组) “29”
%H 小时(24制) “23”
%I 小时(12制) “11”
%M 分钟 “59”
%S 秒 “58”
%e 毫秒 “678”
%f 微秒 “056789”
%F 纳秒 “256789123”
%p AM/PM “AM”
%r 时间(12制) “02:55:02 pm”
%R 时分(24制) “23:55”
%T %X 时间(24制) “23:55:59”
%z 时区(偏移) “+02:00”
%E epoch(秒) “1528834770”
%% 百分号 “%”
%+ 默认格式 “[2014-10-31 23:46:59.678] [mylogger] [info] Some message”
%^ start color range (can be used only once) “[mylogger] [info(green)] Some message”
%$ end color range (for example %^[+++]%$ %v) (can be used only once) [+++] Some message
%@ 文件名与行数 my_file.cpp:123
%s 文件名 my_file.cpp
%g 文件名(含路径) /some/dir/my_file.cpp
%# 行数 123
%! 函数名 my_func
%o 相对上一条记录的时间间隔(毫秒) 456
%i 相对上一条记录的时间间隔(微秒) 456
%u 相对上一条记录的时间间隔(纳秒) 11456
%O 相对上一条记录的时间间隔(秒) 4
日志输出中要携带文件名、行数或函数名时,必须使用SPDLOG_LOGGER_XXX宏,且要激活对应的级别(哪些级别以上的日志会被记录):
如下面定义记录INFO及以上级别日志
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
#include "spdlog/spdlog.h"SPDLOG_LOGGER_INFO(myLogger, "Support for floats {:03.2f}", 1.23456);
SPDLOG_LOGGER_WARN(myLogger, "Easy padding in numbers like {:08d}", 12);
spdlog使用
spdlog默认日志输出级别是INFO。默认情况下,日志是同步模式的,可通过以下方法开启异步模式:
size_t q_size = 4096; //queue size must be power of 2
spdlog::set_async_mode(q_size);
以下方式把日志输出到默认logger上:
#include "spdlog/spdlog.h"int main()
{spdlog::info("{:<30}", "left aligned"); spdlog::warn("Easy padding in numbers like {:08d}", 12);spdlog::error("Some error message with arg: {}", 1); spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42);spdlog::set_level(spdlog::level::debug); // Set global log level to debugspdlog::debug("This message should be displayed.."); // change log patternspdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");}
以彩色方式输出到标准输出设备上:
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"void stdout_example()
{// create color multi threaded loggerauto console = spdlog::stdout_color_mt("console"); auto err_logger = spdlog::stderr_color_mt("stderr"); spdlog::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name)");
}
最简单的日志文件:
#include "spdlog/sinks/basic_file_sink.h"
void basic_logfile_example()
{try {auto logger = spdlog::basic_logger_mt("basic_logger", "logs/basic-log.txt");}catch (const spdlog::spdlog_ex &ex){std::cout << "Log init failed: " << ex.what() << std::endl;}
}
循环文件,日志文件超过指定大小后,自动生成一个新的;并且只保留最多指定数量的日志文件:
#include "spdlog/sinks/rotating_file_sink.h"
// 文件日志定义,设定日志最大100M,且最多保留10个
auto fileLogger = spdlog::rotating_logger_mt("fileLogger", "logs/basic.log", 1024*1024*100, 10);
每天指定时间生成一个新的日志文件:
#include "spdlog/sinks/daily_file_sink.h"
//every day on 2:30am
auto logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
Demo1 文件输出日志:
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"void testSpdLog() {// 文件日志定义,设定日志最大100M,且最多保留10个auto fileLogger = spdlog::rotating_logger_mt("fileLogger", "logs/basic.log", 1024 * 1024 * 100, 10);fileLogger->set_level(spdlog::level::debug);//定义输出格式spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l [thread %t] [%s->%!->%#] - %v");spdlog::set_default_logger(fileLogger);SPDLOG_LOGGER_DEBUG(fileLogger, "test3 {}", 3);for (int i = 0; i < 2; ++i) {SPDLOG_LOGGER_DEBUG(fileLogger, "{}: Hello, {}!", i + 1, "World");SPDLOG_LOGGER_DEBUG(fileLogger, "Welcome to spdlog!");SPDLOG_LOGGER_ERROR(fileLogger, "Some error message with arg: {}", i);}
}
集成Console和文件同步处理日志:
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"void testMultiLog() {//文件sinkauto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_st>("logs/basic.log", 1024 * 1024 * 100, 10);file_sink->set_level(spdlog::level::debug);file_sink->set_pattern("%Y-%m-%d %H:%M:%S.%e %l [thread %t] [%s->%!->%#] - %v");//控制台sinkauto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_st>();console_sink->set_level(spdlog::level::debug);console_sink->set_pattern("%Y-%m-%d %H:%M:%S.%e %l [thread %t] [%s->%!->%#] - %v");std::vector<spdlog::sink_ptr> sinks;sinks.push_back(console_sink);sinks.push_back(file_sink);auto multiLogger = std::make_shared<spdlog::logger>("multiSink", begin(sinks), end(sinks));multiLogger->set_level(spdlog::level::debug);spdlog::set_default_logger(multiLogger);SPDLOG_LOGGER_DEBUG(multiLogger, "test3 {}", 3);for (int i = 0; i < 2; ++i) {SPDLOG_LOGGER_DEBUG(multiLogger, "{}: Hello, {}!", i + 1, "World");SPDLOG_LOGGER_DEBUG(multiLogger, "Welcome to spdlog!");SPDLOG_LOGGER_ERROR(multiLogger, "Some error message with arg: {}", i);}
}
这篇关于日志记录库 spdlog 基础使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!