文章目录

  • Log:Spdlog初探
    • 简介
      • spdlog简介
    • 安装/使用
      • Header only version
      • 编译静态库
        • Linux版本
        • Windows版本
    • 代码说明
      • 设置日志输出样式
      • 基础函数说明
      • 其他特性说明
    • 结尾
      • 简单的代码片段

Log:Spdlog初探

简介

公司需要开新项目,提议更换日志库,交给我让我调研一下spdlog库的使用。

spdlog简介

Github地址:Github地址
官网介绍:Very fast, header-only/compiled, C++ logging library。轻量,仅有头文件/编译,C++日志库。
注意:Spdlog包含了C++11特性,需使用支持C++11特性的编译器。

安装/使用

Header only version

只是用头文件版本。
官网说明:Copy the source folder to your build tree and use a C++11 compiler.
复制源文件文件夹到的你编译链中 和 使用一个C++11编译器。
源文件地址:源文件地址

编译静态库

Linux版本

注意:本机需要安装好git,cmake。这里就不介绍安装git,还有cmake了。

$ git clone https://github.com/gabime/spdlog.git
$ cd spdlog && mkdir build && cd build
$ cmake .. && make -j
$ make install

命令翻译

1.克隆项目到当前目录,工程文件夹为 spdlog
2.进入 spdlog文件夹 && 创建build文件夹 && 进入build文件夹
3.执行cmkae .. 命令构建makefile工程 && make 编译
4.安装。此命令为安装到系统环境中,使用时就不需要配置引用头文件目录,库目录。\
如果不使用改命令,则需要在build 目录下的 lib文件夹找到编译好的库,在 include文件夹 在 引用的头

Windows版本

下载地址:spdlog工程下载地址
Windows下将下载好的 zip包或者 .tar.gz包解压到本地。构建cmake工程
注意:本机需要安装好cmake。cmake下载地址:cmake下载地址,下载版本:cmake-3.17.0-rc3-win64-x64.msi

解压spdlog.zip/spdlog.tar.gz 到 本地
进入spdlog-1.x目录,新建文件夹 build 文件夹,output 文件夹 //配置编译文件夹,编译输出文件夹
打开cmake-gui,配置cmake工程属性 (#后为按钮名称)
配置 CMakeLists.txt 路径,编译路径 #configure
配置 Visual Studio 编译器,平台版本。根据自己需要配置  #Finish
配置 其他属性,主要是 输出目录(安装目录),样例,测试按照默认配置 #configure
等待输出 Generating install / Configuring done  #Generate
等待输出 Generating done cmake工程配置完成
打开VS,打开工程,工程文件目录为build目录 ,工程文件 spdlog.sln
选择ALL_BUILD项目,右键生成。等待生成完成。
选择INSTALL,右键生成。等待安装完成。即可在 output目录看到输出目录(include,lib)
设置 example 为活动项目,查看官方样例。调试查看

配置 CMakeLists.txt 路径,编译路径

配置 Visual Studio 编译器,平台版本。

配置 其他属性

生成完成界面

spdlog 工程目录结构如下

代码说明

设置日志输出样式

相关函数:
默认样式:[2014-10-31 23:46:59.678] [my_loggername] [info] Some message
设置日志输出样式有两种方法

  1. Set the pattern string (recommended):
set_pattern(pattern_string);
  1. mplement custom formatter that implements the formatter interface and call
set_formatter(std::make_unique<my_custom_formatter>());

针对第一种方法:

//应用于全局所有注册的日志样式设置
spdlog::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
//应用于日志对象的样式设置
some_logger->set_pattern(">>>>>>>>> %H:%M:%S %z %v <<<<<<<<<");
//特定的接收器对象
some_logger->sinks()[0]->set_pattern(">>>>>>>>> %H:%M:%S %z %v <<<<<<<<<");
some_logger->sinks()[1]->set_pattern("..");

样式输出参数列表

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 Short log level of the message “D”, “I”, etc
%a Abbreviated weekday name “Thu”
%A Full weekday name “Thursday”
%b Abbreviated month name “Aug”
%B Full month name “August”
%c Date and time representation “Thu Aug 23 15:35:46 2014”
%C Year in 2 digits “14”
%Y Year in 4 digits “2014”
%D or %x Short MM/DD/YY date “08/23/14”
%m Month 01-12 “11”
%d Day of month 01-31 “29”
%H Hours in 24 format 00-23 “23”
%I Hours in 12 format 01-12 “11”
%M Minutes 00-59 “59”
%S Seconds 00-59 “58”
%e Millisecond part of the current second 000-999 “678”
%f Microsecond part of the current second 000000-999999 “056789”
%F Nanosecond part of the current second 000000000-999999999 “256789123”
%p AM/PM “AM”
%r 12 hour clock “02:55:02 pm”
%R 24-hour HH:MM time, equivalent to %H:%M “23:55”
%T or %X ISO 8601 time format (HH:MM:SS), equivalent to %H:%M:%S “23:55:59”
%z ISO 8601 offset from UTC in timezone ([+/-]HH:MM) “+02:00”
%E Seconds since the epoch “1528834770”
%% The % sign “%”
%+ spdlog’s default format “[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 %1%$ %v) (can be used only once) [+++] Some message
%@ Source file and line (use SPDLOG_TRACE(…), SPDLOG_INFO(…) etc.) my_file.cpp:123
%s Basename of the source file (use SPDLOG_TRACE(…), SPDLOG_INFO(…) etc.) my_file.cpp
%g Full path of the source file (use SPDLOG_TRACE(…), SPDLOG_INFO(…) etc.) /some/dir/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
%o Elapsed time in milliseconds since previous message 456
%i Elapsed time in microseconds since previous message 456
%u Elapsed time in nanoseconds since previous message 11456
%O Elapsed time in seconds since previous message 4

自定义样式参数设置
spdlog允许自定义样式参数设置。方法样例如下:
摘自官方样例,不做说明。

#include "spdlog/pattern_formatter.h"
class my_formatter_flag : public spdlog::custom_flag_formatter
{public:void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override{std::string some_txt = "custom-flag";dest.append(some_txt.data(), some_txt.data() + some_txt.size());}std::unique_ptr<custom_flag_formatter> clone() const override{return spdlog::details::make_unique<my_formatter_flag>();}
};void custom_flags_example()
{using spdlog::details::make_unique; // for pre c++14auto formatter = make_unique<spdlog::pattern_formatter>();formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");spdlog::set_formatter(std::move(formatter));
}

基础函数说明

1.设置日志等级

//设置全局注册日志等级
spdlog::set_level(spdlog::level::info); // Set global log level to info
//其他用法与设置日志样式相同

日志等级说明:

//宏定义
#define SPDLOG_LEVEL_TRACE 0
#define SPDLOG_LEVEL_DEBUG 1
#define SPDLOG_LEVEL_INFO 2
#define SPDLOG_LEVEL_WARN 3
#define SPDLOG_LEVEL_ERROR 4
#define SPDLOG_LEVEL_CRITICAL 5
#define SPDLOG_LEVEL_OFF 6
//枚举定义
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
};

2.日志打印函数

//全局注册函数使用方法,使用如下方法默认输出终端/控制台
//info(""); 类似于 printf(),默认参数设置已经完成,()内为具体消息。
//{}. 花括号为参数代表,可以定义为任意支持标准输出格式类型spdlog::info("Welcome to spdlog version {}.{}.{}  !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH);spdlog::warn("Easy padding in numbers like {:08d}", 12);spdlog::critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);spdlog::info("Support for floats {:03.2f}", 1.23456);spdlog::info("Positional args are {1} {0}..", "too", "supported");spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left");
//其他方向,对象/节点 按照对应调用方法即可,

3.backtrace/dump使用

//函数代码来源:官方样例
//enable_backtrace(20); 打开 backtrace/dump 功能,参数为 dump个数spdlog::enable_backtrace(20); // create ring buffer with capacity of 10  messagesfor (int i = 0; i < 100; i++){//注意为设置输出等级之下的日志//spdlog::debug("Backtrace message {}", i); // not logged..}// e.g. if some error happened:spdlog::dump_backtrace(); // log them now!

backtrace/dump 会开辟一个缓冲区,将其他的等级之下的日志保存起来,在需要的时候弹出来。
4.标准输出/控制台打印
标准输出 依赖于 头文件 “spdlog/sinks/stdout_color_sinks.h” 或者 #include “spdlog/sinks/stdout_sinks.h” 区别是 是否支持对输出颜色的设置。

#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
// or #include "spdlog/sinks/stdout_sinks.h" if no colors needed.
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)");
}

5.基础文件输出 Basic file logger

#include "spdlog/sinks/basic_file_sink.h"
void basic_logfile_example()
{try {auto my_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;}
}

6.Rotating file

#include "spdlog/sinks/rotating_file_sink.h"
void rotating_example()
{// Create a file rotating logger with 5mb size max and 3 rotated filesauto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);
}

7.Dailt file
生成日期日志,每天指定时间生成对应的日志文件,也是服务系统中常用的日志,方便定位错误,日常检查

#include "spdlog/sinks/daily_file_sink.h"
void daily_example()
{// Create a daily logger - a new file is created every day on 2:30amauto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30);
}

8.Log binary data in hex

// many types of std::container<char> types can be used.
// ranges are supported too.
// format flags:
// {:X} - print in uppercase.
// {:s} - don't separate each byte with space.
// {:p} - don't print the position on each line start.
// {:n} - don't split the output to lines.#include "spdlog/fmt/bin_to_hex.h"void binary_example()
{auto console = spdlog::get("console");std::array<char, 80> buf;console->info("Binary example: {}", spdlog::to_hex(buf));console->info("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10));// more examples:// logger->info("uppercase: {:X}", spdlog::to_hex(buf));// logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf));// logger->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf));
}

9.异步日志

#include "spdlog/async.h"
#include "spdlog/sinks/basic_file_sink.h"
void async_example()
{// default thread pool settings can be modified *before* creating the async logger:// spdlog::init_thread_pool(8192, 1); // queue with 8k items and 1 backing thread.auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");// alternatively:// auto async_file = spdlog::create_async<spdlog::sinks::basic_file_sink_mt>("async_file_logger", "logs/async_log.txt");
}

10.系统日志

#include "spdlog/sinks/syslog_sink.h"
void syslog_example()
{std::string ident = "spdlog-example";auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID);syslog_logger->warn("This is warning that will end up in syslog.");
}

11.多个日志(Logger with multi sinks - each with different format and log level)

// create logger with 2 targets with different log levels and formats.
// the console will show only warnings or errors, while the file will log all.
void multi_sink_example()
{auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();console_sink->set_level(spdlog::level::warn);console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v");auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", true);file_sink->set_level(spdlog::level::trace);spdlog::logger logger("multi_sink", {console_sink, file_sink});logger.set_level(spdlog::level::debug);logger.warn("this should appear in both console and file");logger.info("this message should not appear in the console, only in the file");
}

其他特性说明

spdlog还支持线程池,异步多线程写日志,线程安全日志,非线程安全日志。
Loggers
To create thread safe loggers, use the _mt factory functions.
线程安全日志 后缀为 _mt

auto logger = spdlog::basic_logger_mt(...);

To create single threaded loggers, use the _st factory functions.
非线程安全 _st

auto logger = spdlog::basic_logger_st(...);

根据项目需求来使用。

结尾

制作了简单介绍,创建与使用,其他复杂的应用还需要在实际项目中使用。最后还是使用了 glog 日志模块。主要想使用 backstrac/dump功能,结果不是预计中,项目奔溃/出错,在日志最后打印错误堆栈信息。测试时还是使用系统信号测试使用。

简单的代码片段

主要功能是,根据系统错误信号,打印错误日志,堆栈日志。其实想法是,每一个类设置对应的信号,错误输出,然后建立一个全局的错误处理。只停留于想法,没有时间做具体的实现。

#include "spdlog/sinks/rotating_file_sink.h"void rotaing_file()
{auto rotating_logger = spdlog::rotating_logger_mt("file_logger","logs/rotating_file.txt",1048576 * 5,3);rotating_logger->set_pattern("[%Y-%m-%d %H:%M:%S] [%l] %! %v");rotating_logger->enable_backtrace(20);rotating_logger->set_level(spdlog::level::trace);rotating_logger->debug("rotating-debug-try {} {} {}", 2019, 03, "01");rotating_logger->info("rotating-info-try {} {} {}", 2019, 03, "01");char * a;memcpy(a, 0, 0);//  rotating_logger->flush();
}void error_handle(int s)
{if (s == SIGSEGV){spdlog::dump_backtrace();}
}void trace_example()
{SPDLOG_TRACE("Some trace message..{},{}",1,3.23);SPDLOG_DEBUG("Some trace message..{},{}",1,3.23);auto logger = spdlog::get("file_logger");SPDLOG_LOGGER_TRACE(logger, "another trace message");
}

  1. +++ ↩︎

Log:Spdlog初探(1)相关推荐

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

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

  2. spdlog日志库的封装使用

    文章目录 前言 spdlog的基本使用 spdlog日志库的封装 前言 编码过程中,日志是必要的一个组件,我们选择使用哪个日志库呢? 参考:15 best C++ Logging libraries ...

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

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

  4. spdlog封装自己的日志库

    先上日志配置定义 struct logger_config {std::string name = "run_logger";spdlog::level::level_enum l ...

  5. c语言log_Morn:一个极简的C语言日志

    Morn:一个C语言的基础工具和基础算法库​github.com Morn的日志是一个极简的,几乎没有学习成本的日志.它可以实现: 多种输出,包括动态文件.控制台.和用户自定义输出. 日志分级,选择性 ...

  6. SLAM本质剖析-Boost

    0. 简介 在深入剖析了Ceres.Eigen.Sophus.G2O后,以V-SLAM为代表的计算方式基本已经全部讲完.就L-SLAM而言,本系列也讲述了PCL.Open3D.与GTSAM点云计算部分 ...

  7. C++系统日志库精选:深入剖析glog与log4cplus,轻松搭建高效日志系统

    目录标题 引言 日志系统的重要性 glog与log4cplus简介与应用场景 C++日志系统库的选择依据 glog基础知识 glog库的关键功能 glog库的安装与使用 glog库的基本日志功能与级别 ...

  8. log库spdlog简介及使用

    spdlog是一个开源的.快速的.仅有头文件的C++11 日志库,code地址在 https://github.com/gabime/spdlog ,目前最新的发布版本为0.14.0.它提供了向流.标 ...

  9. Log:日志之 Spdlog 极简用法示范『二』

    文章目录 关联 背景 用法示范 spdlog 输出到终端 spdlog 输出到文件 其它用法 成系列地址 简 述: 有上一篇中通过日志调研选型,决定采用 Spdlog 后,此篇开始介绍一些基础入门,先 ...

  10. spdlog源码阅读 (1): sinks

    0. spdlog简单介绍 spdlog 是一个快速的 C++ 日志库,只包含头文件,兼容 C++11.项目地址 特性: 非常快 只包含头文件 无需依赖第三方库 支持跨平台 - Linux / Win ...

最新文章

  1. how is batch operation handled in backend
  2. php如何编写通信协议,定制通讯协议
  3. 汉字笔顺口诀_【小学语文知识】汉字书写笔顺口诀+书写规则
  4. 图像处理、分析与机器视觉(基于labview)_基于3D技术的机器视觉解决方案
  5. Photoshop隐藏的4个彩蛋
  6. Eprime的txt数据转换为excel
  7. scala下载和环境搭建
  8. JS逆向-易班登录password参数(RSA加密)
  9. leetcode-739:每日温度
  10. 元宇宙PlatoFarm万众瞩目,同时登录HUOBI等全球四大平台
  11. call cs iub wireshark analysis
  12. echarts 官网访问慢
  13. Java常用加密解密算法全解
  14. 微软再次荣获 Gartner 工业物联网平台魔力象限“领先者”称号
  15. 常用的连续时间信号及其时域特性
  16. 计算机价格谈判议程,价格谈判的几个小技巧
  17. 做独立站如何精准引流
  18. python中变量,Python中的变量、数据类型、运算符
  19. CCF CSP 历年试题题解
  20. Javaweb学生管理系统期末设计

热门文章

  1. DART booster
  2. 泛微oa流程表单之流程阻止提交
  3. shell执行curl_Linux curl命令详解
  4. 《金牌网管师——助理级网吧网管》目录
  5. 写日报、写日报,每天都要写,写工作日报到底有什么意义?
  6. JVM-深入理解JVM内存模型、类加载机制、内存分配机制
  7. 手机共享计算机网络连接,终于找到电脑网络共享给手机
  8. CortexM3/M4(3)-指令集
  9. 窗口函数 OVER(PARTITION BY ...)
  10. 好领导,本来应是挖渠人