为什么选择spdlog?

  • 轻量(header only)
  • 支持异步\backtrace\rotating files\daily file …
  • 文档健全github\ wiki
  • 线程安全
  • 高可拓展

spdlog组成部分

主要由logger(记录器)和sink(接收器)两部分组成。

spdlog的高可拓展体现在logger和sink的可由用户自定义。

logger

主要关注几个要点:

  • logger类型

    • 异步
    • rotating-logger(日志切割)
  • 输出格式(fmt)

  • 日志队列的容量及线程数(并行下的日志顺序问题)

  • 日志级别(level)

  • flush时机

sink

对于sink主要关注输出位置

  • stdout / stderr
  • 文件
  • 数据库 或 其他外部实体

快速上手

spdlog内部为每个进程都维护一张全局Logger记录表,记载了用户每个进程中通过factory method创建的Logger实例(某些情况需要用户手动注册)。因而,在使用Logger时极其方便,只需要知道创建时指定的名称即可。

因此,我们可以通过工厂方法创建一个名为async_file_logger异步Logger,输出到/logs/async_log.txt

auto async_file = spdlog::basic_logger_mt<spdlog::async_factory>("async_file_logger", "logs/async_log.txt");

在需要用的get

auto logger = spdlog::get("async_file_logger");
logger->info("some things want to say.");

在默认情况下,spdlog为我们设置了写到标准输出的logger,
我们可以通过set_default_logger进行调整

spdlog::set_default_logger(some_other_logger);

一般情况下,我们需要Logger同时具备日志切割及异步输出的功能,在spdlog中我们可以使用factory methd —— rotating_logger_mt


更多具体的例子请参考spadlog wiki, 里面的具有丰富的sample、tutorial、api描述以及注意事项,比log4cpp要健全得多。

拥有完善的文档是对所有开发者最大的敬意。


封装Demo级别的Log

主要实现以下功能

  1. 支持异步输出日志
  2. 支持日志切割
  3. 单个线程负责写文件
  4. warn级别日志输出到stdout, 全部信息都需要写入文件
  5. 只有定义DEBUG宏,才开启写入DEBUG信息

用法

#define DEBUG#include "log.h"int main(void) {init_logger();// ... ...spdlog::info("Log Demo");return 0;
}

实现

#ifdef DEBUG
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
// #define SPDLOG_DEBUG_ON
#endif#include <spdlog/spdlog.h>
#include <spdlog/async.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/basic_file_sink.h>/* basic */
constexpr const char* filename = "logs/log.txt";
/* rotating file config */
constexpr int file_size  = 10*1024*1024; // 10M
constexpr int back_count = 5;/* async sink config */
constexpr int task_count = 1024 * 8;
constexpr int tp_size    = 1;static inline void init_logger(){// create console_sinkauto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();console_sink->set_level(spdlog::level::warn);// create rotating file sinkauto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(filename, file_size, back_count, false);
#ifdef DEBUGfile_sink->set_level(spdlog::level::debug);
#elsefile_sink->set_level(spdlog::level::info);
#endif// sink's bucketspdlog::sinks_init_list sinks{console_sink, file_sink};// create async logger, and use global threadpoolspdlog::init_thread_pool(task_count, tp_size);auto logger = std::make_shared<spdlog::async_logger>("aslogger", sinks, spdlog::thread_pool());// ajust level.
#ifdef DEBUGlogger->set_level(spdlog::level::debug);
#elselogger->set_level(spdlog::level::info);
#endifspdlog::register_logger(logger);spdlog::set_default_logger(logger);
}

一个坑点

若你希望看到DEBUG或是TRACE级别的信息,你需要使用以下东西:

// 或 SPDLOG_LEVEL_TRACE
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG// 或 spdlog::set_level(spdlog::level::trace);
spdlog::set_level(spdlog::level::debug);

经过笔者测试(TRACE也是同理,不多赘述)

  • 当仅使用spdlog::set_level(spdlog::level::debug)而不设置宏SPDLOG_ACTIVE_LEVEL时,
    只有以下方法会生效

    spdlog::debug()
    
  • 同时使用spdlog::set_level(spdlog::level::debug)并设置SPDLOG_ACTIVE_LEVEL
    时,所有相关的操作都会生效

    spdlog::debug()
    SPDLOG_DEBUG()
    SPDLOG_LOGGER_DEBUG()
    
  • 当仅设置SPDLOG_ACTIVE_LEVEL为DEBUG级别时,所有DEBUG及以下级别的输出都将被忽略

注意: 如果你使用spdlog::set_level,而且是手动构造的logger,那么最好将logger先通过spdlog::register_logger将相应的logger注册到全局表中。因为,在通常的情况下,形如spdlog::*的相关设置只会影响已经注册到全局表中的logger。相似的,spdlog::initialzie_logger被用于设置log level和 formatter(输出格式)的同时将logger注册到全局表中。

参考: spdlog::set_default_logger(logger) will cause spdlog::set_level(spdlog::level::debug) to fail

spdlog入门概要相关推荐

  1. 目标检测(Object Detection)入门概要

    Objection Detection Tasks Methods Algorithms Region Proposal Selective Search EdgeBoxes R-CNN SPP-Ne ...

  2. Spring MVC 入门概要 1

    (1):编写 Entity Model  [get set方法] (2):编写配置文件,设置    实体类,简称 -设置别名 <typeAliases><typeAlias alia ...

  3. 出于对Java入门学习的考虑从Java基础出发

    看到过无数套毫无用处的Java路线图,到现在为止还在云端飘着,对于Java小白来说就像天书一般,Java大神看了以后感觉云山雾绕不知道讲什么东西,动力节点Java学院作为Java业界标杆深意为耻,于是 ...

  4. YOLOv5s的模型训练与使用(纯小白入门)

    YOLOv5s的模型训练与使用(纯小白入门) 文章目录 YOLOv5s的模型训练与使用(纯小白入门) 概要 下载yolov5与安装依赖 训练 检测 检测图片 实时检测视频 概要 本文主要面向第一次使用 ...

  5. java路线_2021年Java学习路线图—精心整理

    看到过无数套毫无用处的Java路线图,到现在为止还在云端飘着,对于Java小白来说就像天书一般,Java大神看了以后感觉云山雾绕不知道讲什么东西,于是我从实战出发,呕心沥血整理出来Java学习路线图希 ...

  6. Java学习路线图—精心整理 java进阶

    看到过无数套毫无用处的Java路线图,到现在为止还在云端飘着,对于Java小白来说就像天书一般,Java大神看了以后感觉云山雾绕不知道讲什么东西,动力节点Java学院作为Java业界标杆深意为耻,于是 ...

  7. redis入门综合概要介绍

    redis入门综合概要介绍 概要介绍:个人感觉redis是一个将数据保存在内存的存取工具,类似一个增强的Map,所以存取比较快.数据的存取基本上是set(key,value),get(key)这种ke ...

  8. 初学者对PHP的总结,PHP_献给php初学者(入门学习经验谈),1.概要:学习任何语言都需要 - phpStudy...

    献给php初学者(入门学习经验谈) 1.概要:学习任何语言都需要 多看 多想 多写 多问!!写编程是一种熟能生巧的东西!因为知识就那么多,你看多了就会觉得怎么都一样. 程序员就是炒冷饭的,一遍又一遍. ...

  9. MapRedues(一) 概要编程入门

    MapRedues(一) 概要&编程入门@你宝爷 一.概述 1.1.基本概念 MapReduce是一个基于Hadoop集群的分布式计算编程框架,用户通过编写业务逻辑代码和自带默认组件结合成一个 ...

最新文章

  1. OpenCV识别形状
  2. Android targetSdkVersion 原理
  3. 【Linux 内核 内存管理】Linux 内核堆内存管理 ① ( 堆内存管理 | 内存描述符 mm_struct 结构体 | mm_struct 结构体中的 start_brk、brk 成员 )
  4. Android Studio 小技巧/快捷键 合集
  5. C语言——第六周作业
  6. java-数据结构-续
  7. Kafka 配置参数汇总及相关说明
  8. 百炼-2701:与7无关的数
  9. PHP Smarty 学习手册
  10. PayPal支付配置
  11. 2021年山东省安全员C证报名考试及山东省安全员C证操作证考试
  12. 14个免费的 GIS 软件:以开源的方式绘制地图
  13. 【001】半电池的开路电压测试_#LIB
  14. 如何提高公寓房屋出租率?
  15. switch日版有中文吗_Switch中文系统更新方法 NS怎么设置中文系统语言
  16. local function definitions are illegal
  17. 常用激活函数:Sigmoid、Tanh、Relu、Leaky Relu、ELU、Mish、Swish等优缺点总结
  18. python如何使用matplotlib画散点图使不同类别的点有不同的形状和颜色?
  19. CC, TBD, EOD都是什么鬼?拯救一写英文邮件就发慌
  20. 使用nat123进行内网穿透

热门文章

  1. CAD二次开发--二维多段线Polyline与三维多段线Polyline3d创建总结
  2. CAD中的dxf文件解析(三):多段线篇
  3. chapter4——时钟分频器
  4. java int长度_JAVA 基本数据类型长度
  5. windows批处理命令通过修改注册表快捷开关Internet代理
  6. 【神回复】程序员30多岁还在投简历找工作,怎么看?
  7. 电商平台如何统一实现支付和分账?
  8. 网红考研老师张雪峰被人泼鲱鱼罐头,回应:竞争对手所为!
  9. vue给同一元素绑定单击click和双击事件dblclick,执行不同逻辑
  10. 注册公司法人与股东哪个风险大