C++Spdlog学习笔记

  • spdlog简介
  • spdlog优点
  • 一般日志功能设计
  • spdlog安装
  • spdlog琐碎知识点总结
  • spdlog程序测试
    • (一)日志输出控制台
      • (1)数据全部输出到控制台
      • (2)指定某个等级以上的数据到控制台
    • (二)输出格式的自定义方式
    • (三)数据输出到文件
      • (1)三种创建文件的方式

spdlog简介

(1)按照官方介绍,是一个高性能的C++日志组件,支持跨平台,兼容 C++11;一款开源的、快速的日志库;
(2)spdlog是个只有头文件的库,只需要将头文件拷贝到你的工程就可以使用了,编译器需要支持C++11
它使用一个类似python的格式API库fmt:

spdlog优点

  1. 配置特别简单,仅包含头文件即可(我暂时没测试成功 在我测试时需要引入静态库)
  2. 写日志方式简单明了;
  3. 可实现自动按日期创建日志文件/定时创建日志文件;
  4. 可自定义日志格式;
  5. 可以输出当前输出日志所在的文件及函数;
  6. 可自定义文档大小;
  7. 可将不同级别的信息输出到不同日志文件;
  8. 多平台等。

一般日志功能设计

一般在实际工作中,日志最好要有以下3个功能:
①:自动按日期创建日志文件;
②:自动定期清理过期日志(spdlog好像没有这个功能…);
③:实时刷新日志。
具体分析:
①:一天只创建一个日志文件(或者将各级别的日志单独创建为一个文件)是为了更加清晰简洁,若程序在每次开启时都创建一个日志文件,可能就会显得很混乱。
②:一般时间较久的日志不再具有参考价值,如果真是现场出现问题,用户也不会等很久才反馈。所以一般保存7天内的日志就足够了。
③:当我们需要查看日志时,但又不能关闭现场程序,那么就需要能实时刷新日志信息。不然我们可能会遇到日志文件打不开或者打开以后日志信息未更新的问题。

spdlog安装

[1] 安装配置测试链接
[2] Vcpkg全自动方式
[3] C++参考手册
[4] 总体概括

spdlog琐碎知识点总结

(1)线程安全:spdlog:: 命名空间下的是线程安全的;类似于:spdlog::set_error_handler(log_err_handler); // or logger->set_error_handler(log_err_handler);
(2)对于sinks,以 _mt 后缀结尾的是线程安全的,比如:daily_file_sink_mt,以_st 后缀结尾的是非线程安全的,比如:daily_file_sink_st
(3)有关异步设置logger – 多线程 – (4)中相关细节也可查看
(4)使用spdlog::get("...")访问loggers缺点:loggers可以在任何地方使用线程安全的spdlog::get("logger_name")来进行访问,返回智能指针;注意:spdlog::get可能会拖慢你的程序,因为它内部维护了一把锁,所以要谨慎使用。比较推荐的用法是保存返回的shared_ptr<spdlog::logger>,直接使用它,至少在频繁访问的代码中。详情参考(3)链接

spdlog程序测试

(一)日志输出控制台

链接中包含cmake文件配置

(1)数据全部输出到控制台

spdlog灵魂所在:自动识别类型,避免%d,%s类型错误,输出不了内容或者崩溃

LogDebug(“cmd_id={},bodyLen={}”, 1, 2);
LogInfo(“user_id={},app_id={},domainId={},ip={},port={}”, 222, 222, 222, “127.0.0.1”, 8888);

#include <iostream>
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
int main01(int argc, char* argv[])
{/*创建一个控制台对象*/auto console = spdlog::stdout_color_mt("ybhy");/*在控制台输出以下数据 -- 不同的等级有不同的颜色对应 :info、error、warn、critical*/console->info("信息");console->warn("警告");console->error("错误");console->critical("危险");/*上面的另一种写法*/spdlog::info("信息");spdlog::warn("警告");spdlog::error("错误");spdlog::critical("危险");/*根据对象输出到控制台 -- 类似于指定用户那种*/console->info("Welcome to spdlog!");console->info("Support for floats {:03.2f}", 1.23456);console->info("Positional args are {1} {0}..", "too", "supported");console->info("{:<30}", "left aligned");console->warn("Easy padding in numbers like {:08d}", 12);console->error("Some error message with arg{}..", 1);console->critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);/*通过 get() 方法获取 相关对象指针 -- 输入相关数据*/spdlog::get("ybhy")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");/*显示格式*/spdlog::set_pattern("[%Y-%m-%d %H:%M:%S] [%l] [%n],%v");/*关闭所有logger对象*/spdlog::drop_all();return 0;
}

运行结果如下

(2)指定某个等级以上的数据到控制台

spdlog::set_level(spdlog::level::warn);

enum level_enum //等级表
{
trace = SPDLOG_LEVEL_TRACE, // 最低
debug = SPDLOG_LEVEL_DEBUG,
info = SPDLOG_LEVEL_INFO,
warn = SPDLOG_LEVEL_WARN,
err = SPDLOG_LEVEL_ERROR,
critical = SPDLOG_LEVEL_CRITICAL, // 最高
off = SPDLOG_LEVEL_OFF,
n_levels
};

#include <iostream>
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
int main01(int argc, char* argv[])
{/*创建一个控制台对象*/auto console = spdlog::stdout_color_mt("ybhy");/*设计运行等级 -- 等级以下 不显示 相当于 warn以下的信息不打印*/spdlog::set_level(spdlog::level::warn); /*在控制台输出以下数据 -- 不同的等级有不同的颜色对应 :info、error、warn、critical*/console->info("信息");console->warn("警告");console->error("错误");console->critical("危险");/*上面的另一种写法*/spdlog::info("信息");spdlog::warn("警告");spdlog::error("错误");spdlog::critical("危险");/*根据对象输出到控制台 -- 类似于指定用户那种*/console->info("Welcome to spdlog!");console->info("Support for floats {:03.2f}", 1.23456);console->info("Positional args are {1} {0}..", "too", "supported");console->info("{:<30}", "left aligned");console->warn("Easy padding in numbers like {:08d}", 12);console->error("Some error message with arg{}..", 1);console->critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);/*通过 get() 方法获取 相关对象指针 -- 输入相关数据*/spdlog::get("ybhy")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name) function");/*显示格式*/spdlog::set_pattern("[%Y-%m-%d %H:%M:%S] [%l] [%n],%v");return 0;
}

运行结果如下

(二)输出格式的自定义方式

熟悉函数:spdlog::set_pattern("[%Y-%m-%d %H:%M:%S] [%l] [%n],%v");

  1. 模式标记
flag meaning example
%v The actual text to log(要记录的实际文本) “some user text”
%t Thread id “1232”
%P Process id “3456”
%n Logger’s name “some logger name”
%l The log level of the message “debug”, “info”, etc
%L The log level of the message “D”, “I”, etc
%a Abbreviated weekday name(工作日的缩写) “Thu”
%@ Source file and line (use SPDLOG_TRACE(…),SPDLOG_INFO(…) etc.) my_file.cpp:123
%s Source file (use SPDLOG_TRACE(…),SPDLOG_INFO(…) etc.) my_file.cpp
%# Source line (use SPDLOG_TRACE(…),SPDLOG_INFO(…) etc.) 123
%! Source function (use SPDLOG_TRACE(…),SPDLOG_INFO(…) etc. see tweakme for pretty-print) my_func
  1. 对齐
  2. 相关程序测试

细节把握
(1)spdlog::set_pattern("[%Y-%m-%d %H:%M:%S] [%l] [%n],%v"); 可以放在最后(显示的时候会根据不同的level显示不同的颜色),可以放在最前(无颜色)
(2)在使用<%@><%s><%#><%!> 不是直接写上就可以,需要调用相对应的函数宏才可实现;目前调研中掌握了两种方法:①通过调用宏函数 ②自己编写一个函数宏来调用本身程序;
(3)具体实现:①通过调用宏函数:引入#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE,在程序中调用对应宏,比如:SPDLOG_LOGGER_INFO(spdlog::get("ybhy"),"faf"); ②自己编写一个函数宏来调用本身程序:如下代码所示:

#include <iostream>
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/stdout_color_sinks.h"
/*以下宏函数将信心打印到控制台和文件*/
#define DEBUG(...) SPDLOG_LOGGER_DEBUG(spdlog::default_logger_raw(), __VA_ARGS__);SPDLOG_LOGGER_DEBUG(spdlog::get("daily_logger"), __VA_ARGS__)
#define LOG(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__);SPDLOG_LOGGER_INFO(spdlog::get("daily_logger"), __VA_ARGS__)
#define WARN(...) SPDLOG_LOGGER_WARN(spdlog::default_logger_raw(), __VA_ARGS__);SPDLOG_LOGGER_WARN(spdlog::get("daily_logger"), __VA_ARGS__)
#define ERROR(...) SPDLOG_LOGGER_ERROR(spdlog::default_logger_raw(), __VA_ARGS__);SPDLOG_LOGGER_ERROR(spdlog::get("daily_logger"), __VA_ARGS__)int main(int argc, char* argv[])
{// 每天2:30 am 新建一个日志文件auto logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);// 遇到warn flush日志,防止丢失logger->flush_on(spdlog::level::warn);//每三秒刷新一次spdlog::flush_every(std::chrono::seconds(10));//将默认记录器设置为文件记录器auto console = spdlog::stdout_color_mt("ybhy");spdlog::set_default_logger(console);spdlog::set_level(spdlog::level::debug); // Set global log level to debug//打印相关信息LOG("test info");//将信息打印到控制台和文件ERROR("test error");WARN("dadasda");// %s:文件名// %#:行号// %!:函数名spdlog::set_pattern("[%Y-%m-%d %H:%M:%S] [%l] [%n] - <%@>,%v");spdlog::drop_all();return 0;
}

运行结果如下

答疑:为什么文件中写进的是“daily_logger”。而控制台是“ybhy”,是因为两者的logger对象不一致’
细节:在写入文件时注意:spdlog::set_level(spdlog::level::err);,如果你设计成“err”,那么文件中也只会保存等级为“error”以上的数据

(三)数据输出到文件

(1)三种创建文件的方式

  1. basic_logger_mt
    a:说明:日志文件一直会被写入,不断变大
    b:案例:

    auto my_logger = spd::basic_logger_mt("basic_logger", "logs/basic-log.txt");
    my_logger->info("Some log message");
    
  2. rotating_logger_mt
    a:说明:滚动日志,当日志文件超出规定大小时,会删除当前日志文件中所有内容,重新开始写入
    b:函数原型:rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
    c:参数介绍:参数max_files 规定了滚动文件的个数。当logger_name存满时,将其名称更改为logger_name.1,再新建一个logger_name文件来存储新的日志。再次存满时,把logger_name.1改名为logger_name.2,logger_name改名为logger_name.1,新建一个logger_name来存放新的日志。max_files 数量为几,就可以有几个logger_name文件用来滚动。
    d:案例:

    auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 256, 2);
    for (int i = 0; i < 10; ++i)rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);
    

    e:测试结果
    每个文件内容如下,后缀数字越大,日志内容越早:

  3. daily_logger_mt
    a:说明:每天会新建一个日志文件,新建日志文件的时间可自己设定
    b:案例:

        // Create a daily logger - a new file is created every day on 2:30amauto daily_logger = spd::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);// trigger flush if the log severity is error or higherdaily_logger->flush_on(spd::level::err);daily_logger->info(123.44);
    

    c:测试结果:

C++spdlog学习总结相关推荐

  1. spdlog学习笔记

    说明:所有内容翻译自spdlog的wiki,受英语水平所限,有所错误或失真在所难免,如果您有更好的建议,请在博文下留言. 线程安全 spdlog:: 命名空间下的是线程安全的,当loggers在不同的 ...

  2. spdlog 日志库学习,自定义 sink

    spdlog wiki:https://github.com/gabime/spdlog/wiki 别人的学习笔记:https://www.cnblogs.com/oucsheep/p/8426548 ...

  3. spdlog 日志库学习,简易封装

    spdlog wiki:https://github.com/gabime/spdlog/wiki 别人的学习笔记:https://www.cnblogs.com/oucsheep/p/8426548 ...

  4. 资源 | 做一款炫酷的机器人需要哪些学习资源(机器人资源Awesome系列)

    翻译 | AI科技大本营 参与 | 赵博 SuiSui 为什么要制作机器人呢?想参加各种机器人大赛?看起来很炫酷?不过从学习角度说,机器人综合了信息技术.电子工程.机械学.程序设计.控制系统以及认知等 ...

  5. opencv生成日志_OpenCV-Utils学习日志:VideoCapture使用样例

    1.VideoCapture可以打开多种来源的数据流,但常见的是相机.视频及图像序列三类数据流: (1)打开相机数据流,需要指定相机在主机上的设备编号,若主机上只有一个相机则编号通常是0. (2)打开 ...

  6. Hazel引擎学习(四)

    我自己维护引擎的github地址在这里,里面加了不少注释,有需要的可以看看 Hazel引擎是dll还是lib? 引擎作为dll的优点: hotswapping code Easy to Link 引擎 ...

  7. Hazel引擎学习(三)

    我自己维护引擎的github地址在这里,里面加了不少注释,有需要的可以看看 一. Layer 设计完Window和Event之后,需要创建Layer类.Layer这个概念比较抽象,具体在游戏里,比如游 ...

  8. Hazel引擎学习(一)

    我自己维护引擎的github地址在这里,里面加了不少注释,有需要的可以看看 Project Setup 1.SetUp项目,生成的文件在bin目录下,生成的intermediate文件在bin-int ...

  9. c++日志库实战——spdlog,是不是感觉log4cxx有点笨重,不妨试一试spdlog

    c++日志库实战--spdlog,是不是感觉log4cxx有点笨重,不妨试一试spdlog 背景 更新记录 spdlog是什么 spdlog快速入门 编译 CMake手动方式 Vcpkg全自动方式(推 ...

最新文章

  1. 基于Hadoop的MapReduce框架研究报告
  2. UA MATH574M 统计学习II 二元分类例子与高维问题
  3. 初探云原生应用管理(二): 为什么你必须尽快转向 Helm v3
  4. Web UI 用户管理部分 Bug报告
  5. 通过一个简单的例子,了解如何单步调试 Cypress 代码
  6. LeetCode LCP 06. 拿硬币
  7. 阿里云服务器内核编译升级
  8. php codeigniter cookie,PHP 使用CodeIgniter删除、设置Cookie的简单示例
  9. 用VC实现洪水***程序
  10. oracle数据库服务器名称修改,oracle数据库服务器名称修改
  11. JavaScript学习手册四:JS对象
  12. 删除卸载企业微信后的残留文件
  13. 一个公式,把营销从玄学变回科学
  14. Swift学习笔记 (四十二) 不透明类型
  15. 《问题笔记》【Visual Studio】 webView.LoadUrl(“file:///android_asset/mypage.html“)本地页面出现Invalid file path情况
  16. 考研英语不熟悉的词义(List16-List20)
  17. Libpcap Libnet 各个接口pai 巨细
  18. 用html做网站古诗春思,春思古诗词
  19. 【MCU】单片机看门狗工作原理
  20. c++ windows网络编程底层涉及库

热门文章

  1. 如何完全删除Win7系统下用户配置文件
  2. python让你再也不为文章配图与素材发愁,让高清图片占满你的硬盘!
  3. [译] Python 的时间序列分析:简介
  4. 知己知彼百战不殆(希望能有更多的人看到并使你们有所收获)
  5. 程序员炫技:探索高级编程之美
  6. 怎样用“中台”割企业的韭菜?
  7. 华为EMUI10升级名单曝光,共33款机型,看看你的华为手机在内吗
  8. 进销存软件怎么管理门店库存?
  9. TCP协议的客户端和服务器端通信
  10. 数据分析中-比python更趁手的兵器-下篇