日志记录库 spdlog 基础使用

2023-11-01 17:20

本文主要是介绍日志记录库 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 基础使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/324540

相关文章

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen

Pandas使用AdaBoost进行分类的实现

《Pandas使用AdaBoost进行分类的实现》Pandas和AdaBoost分类算法,可以高效地进行数据预处理和分类任务,本文主要介绍了Pandas使用AdaBoost进行分类的实现,具有一定的参... 目录什么是 AdaBoost?使用 AdaBoost 的步骤安装必要的库步骤一:数据准备步骤二:模型

使用Pandas进行均值填充的实现

《使用Pandas进行均值填充的实现》缺失数据(NaN值)是一个常见的问题,我们可以通过多种方法来处理缺失数据,其中一种常用的方法是均值填充,本文主要介绍了使用Pandas进行均值填充的实现,感兴趣的... 目录什么是均值填充?为什么选择均值填充?均值填充的步骤实际代码示例总结在数据分析和处理过程中,缺失数

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

解决Maven项目idea找不到本地仓库jar包问题以及使用mvn install:install-file

《解决Maven项目idea找不到本地仓库jar包问题以及使用mvninstall:install-file》:本文主要介绍解决Maven项目idea找不到本地仓库jar包问题以及使用mvnin... 目录Maven项目idea找不到本地仓库jar包以及使用mvn install:install-file基

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

C 语言中enum枚举的定义和使用小结

《C语言中enum枚举的定义和使用小结》在C语言里,enum(枚举)是一种用户自定义的数据类型,它能够让你创建一组具名的整数常量,下面我会从定义、使用、特性等方面详细介绍enum,感兴趣的朋友一起看... 目录1、引言2、基本定义3、定义枚举变量4、自定义枚举常量的值5、枚举与switch语句结合使用6、枚

使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)

《使用Python从PPT文档中提取图片和图片信息(如坐标、宽度和高度等)》PPT是一种高效的信息展示工具,广泛应用于教育、商务和设计等多个领域,PPT文档中常常包含丰富的图片内容,这些图片不仅提升了... 目录一、引言二、环境与工具三、python 提取PPT背景图片3.1 提取幻灯片背景图片3.2 提取

使用Python实现图像LBP特征提取的操作方法

《使用Python实现图像LBP特征提取的操作方法》LBP特征叫做局部二值模式,常用于纹理特征提取,并在纹理分类中具有较强的区分能力,本文给大家介绍了如何使用Python实现图像LBP特征提取的操作方... 目录一、LBP特征介绍二、LBP特征描述三、一些改进版本的LBP1.圆形LBP算子2.旋转不变的LB

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H