日志记录库 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

相关文章

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

如何使用Lombok进行spring 注入

《如何使用Lombok进行spring注入》本文介绍如何用Lombok简化Spring注入,推荐优先使用setter注入,通过注解自动生成getter/setter及构造器,减少冗余代码,提升开发效... Lombok为了开发环境简化代码,好处不用多说。spring 注入方式为2种,构造器注入和setter

MySQL中比较运算符的具体使用

《MySQL中比较运算符的具体使用》本文介绍了SQL中常用的符号类型和非符号类型运算符,符号类型运算符包括等于(=)、安全等于(=)、不等于(/!=)、大小比较(,=,,=)等,感兴趣的可以了解一下... 目录符号类型运算符1. 等于运算符=2. 安全等于运算符<=>3. 不等于运算符<>或!=4. 小于运

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

Python 字典 (Dictionary)使用详解

《Python字典(Dictionary)使用详解》字典是python中最重要,最常用的数据结构之一,它提供了高效的键值对存储和查找能力,:本文主要介绍Python字典(Dictionary)... 目录字典1.基本特性2.创建字典3.访问元素4.修改字典5.删除元素6.字典遍历7.字典的高级特性默认字典

Zabbix在MySQL性能监控方面的运用及最佳实践记录

《Zabbix在MySQL性能监控方面的运用及最佳实践记录》Zabbix通过自定义脚本和内置模板监控MySQL核心指标(连接、查询、资源、复制),支持自动发现多实例及告警通知,结合可视化仪表盘,可有效... 目录一、核心监控指标及配置1. 关键监控指标示例2. 配置方法二、自动发现与多实例管理1. 实践步骤

使用Python构建一个高效的日志处理系统

《使用Python构建一个高效的日志处理系统》这篇文章主要为大家详细讲解了如何使用Python开发一个专业的日志分析工具,能够自动化处理、分析和可视化各类日志文件,大幅提升运维效率,需要的可以了解下... 目录环境准备工具功能概述完整代码实现代码深度解析1. 类设计与初始化2. 日志解析核心逻辑3. 文件处

一文详解如何使用Java获取PDF页面信息

《一文详解如何使用Java获取PDF页面信息》了解PDF页面属性是我们在处理文档、内容提取、打印设置或页面重组等任务时不可或缺的一环,下面我们就来看看如何使用Java语言获取这些信息吧... 目录引言一、安装和引入PDF处理库引入依赖二、获取 PDF 页数三、获取页面尺寸(宽高)四、获取页面旋转角度五、判断

C++中assign函数的使用

《C++中assign函数的使用》在C++标准模板库中,std::list等容器都提供了assign成员函数,它比操作符更灵活,支持多种初始化方式,下面就来介绍一下assign的用法,具有一定的参考价... 目录​1.assign的基本功能​​语法​2. 具体用法示例​​​(1) 填充n个相同值​​(2)

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命