spdlog一个非常好用的C++日志库(八): 自定义格式化符号

目录

1.前言

2.使用set_pattern(..)自定义格式符号

3.格式化标记符(Pattern flags)

4.对齐方式

5.扩展spdlog自定义格式


1.前言

        每个记录器的接收器sink都有一个格式化器,用于将消息格式化到其目的地。

        spdlog的默认日志记录格式为:  

  [2014-10-31 23:46:59.678]  [my_loggername]  [info]  Some message

        有两种方法可以自定义记录器的格式:

         1)设置模式字符串(推荐):

     set_pattern(pattern_string);

         2)  实现实现格式化程序接口和调用的自定义格式化程序:

     set_formatter(std::make_unique<my_custom_formater>());

2.使用set_pattern(..)自定义格式符号

格式可以全局应用于所有注册的记录器 loggers:

spdlog::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");

或者用于特定的记录器 loggers:

some_logger->set_pattern(">>>>>>>>> %H:%M:%S %z %v <<<<<<<<<");

或者用于特定sink对象:

some_logger->sinks()[0]->set_pattern(">>>>>>>>> %H:%M:%S %z %v <<<<<<<<<");
some_logger->sinks()[1]->set_pattern("..");

3.格式化标记符(Pattern flags)

 格式化标记符以%flag的形式出现,类似于strftime函数。以下是一些常用的模式标志及其含义:

标记 含义 例子
%v

要记录的实际文本

"some user text"
%t

线程ID

"1232"
%P

进程ID

"3456"
%n

logger的名称

"some logger name"
%l

消息的日志级别(如"debug"、"info"等)

"debug", "info", etc
%L

消息的简短日志级别(如"D"、"I"等)

"D", "I", etc
%a

星期几的缩写

"Thu"
%A

星期几的全称

"Thursday"
%b

月份的缩写

"Aug"
%B

月份的全称

"August"
%c

日期和时间的表示

"Thu Aug 23 15:35:46 2014"
%C

年份的两位表示

"14"
%Y

年份的四位数表示

"2014"
%或  %x

短日期格式(MM/DD/YY)

"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 时间表示法 "02:55:02 PM"
%R 时间表示法 "23:55"
%T 或 %X 时间表示法 "23:55:59"
%z ISO 8601与UTC的时区偏移量([+/-]HH:MM) "+02:00"
%E 自纪元以来的秒数 "1528834770"
%% %符号 "%"
%+ spdlog默认的格式 "[2014-10-31 23:46:59.678] [mylogger] [info] Some message"
%^

开始颜色范围

"[mylogger] [info(green)] Some message"
%$

结束颜色范围

[+++] Some message
%@ 源文件和行号 /some/dir/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

注意:如果你需要使用源代码定位相关的符号 %s%g%#%!,那你必须定义下面的宏:

#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_TRACE

(根据需要更改日志级别)并使用以下宏:

SPDLOG_LOGGER_TRACE(some_logger, "trace message");
SPDLOG_LOGGER_DEBUG(some_logger, "debug message");
SPDLOG_LOGGER_INFO(some_logger, "info message");
SPDLOG_LOGGER_WARN(some_logger, "warn message");
SPDLOG_LOGGER_ERROR(some_logger, "error message");
SPDLOG_LOGGER_CRITICAL(some_logger, "critical message");

打开SPDLOG_LOGGER_INFO、SPDLOG_LOGGER_CALL的宏定义:

#    define SPDLOG_LOGGER_INFO(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::info, __VA_ARGS__)
#    define SPDLOG_INFO(...) SPDLOG_LOGGER_INFO(spdlog::default_logger_raw(), __VA_ARGS__)

#define SPDLOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__)

明白了把,SPDLOG_LOGGER_CALL宏把spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}  传进去了,所以能打印源代码的位置和函数名了。

4.对齐方式

每个符号标志可以通过预先设置宽度数字(最多64)来对齐。
使用 "-"(左对齐)或 "="(居中对齐)控制对齐边:

对齐 含义 例子 结果
%<width><flag> 右对齐 %8l "    info"
%-<width><flag> 左对齐 %-8l "info    "
%=<width><flag> 中间对齐 %=8l "  info  "

可选添加!如果结果的大小超过指定的宽度,则截断该结果:

对齐 含义 例子 结果
%<width>!<flag> 右对齐或截断 %3!l "inf"
%-<width>!<flag> 左对齐或截断 %-2!l "in"
%=<width>!<flag> 中间对齐或截断 %=1!l "i"

5.扩展spdlog自定义格式

        在spdlog中,扩展自定义标志允许您根据自己的需求定义新的日志格式标志。这通过继承custom_flag_formatter类并实现其clone()和format(...)抽象方法来完成。以下是如何在spdlog中扩展自定义标志的详细步骤:

        步骤 1: 继承 custom_flag_formatter 类

        首先,您需要创建一个继承自spdlog::custom_flag_formatter的类。在这个类中,您将定义您的新标志的逻辑。

        步骤 2: 实现 clone() 方法

        clone()方法需要返回一个当前对象的深拷贝。这是因为在spdlog中,每个接收器(sink)都会获得格式化器的一个新副本,以确保线程安全和避免潜在的竞态条件。

        步骤 3: 实现 format(...) 方法

        format(...)方法定义了当遇到您的自定义标记时,应该如何格式化日志消息。这个方法接收日志消息、时间戳和一个缓冲区,您需要将格式化后的文本追加到这个缓冲区中。

        以下是一个示例,展示了如何添加一个名为%*的新自定义标志,该标志将向日志消息中添加自定义文本。

#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()
{    
    auto formatter = std::make_unique<spdlog::pattern_formatter>();
    formatter->add_flag<my_formatter_flag>('*').set_pattern("[%n] [%*] [%^%l%$] %v");
    spdlog::set_formatter(std::move(formatter));
}

        请注意,上述示例中的(...)方法只是简单地添加了一段静态文本到日志消息中。根据您的具体需求,您可以在这个方法中添加更复杂的逻辑来格式化日志消息。

相关推荐

  1. 超级C++实用日志

    2024-07-11 03:46:01       31 阅读
  2. 05_c/c++开源 spdlog日志

    2024-07-11 03:46:01       33 阅读
  3. c# 一个定义日志

    2024-07-11 03:46:01       14 阅读
  4. python非常文件系统监控

    2024-07-11 03:46:01       61 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 03:46:01       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 03:46:01       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 03:46:01       58 阅读
  4. Python语言-面向对象

    2024-07-11 03:46:01       69 阅读

热门阅读

  1. QT入门详解含源码)

    2024-07-11 03:46:01       27 阅读
  2. 前端程序员常用快捷键

    2024-07-11 03:46:01       24 阅读
  3. React@16.x(54)Redux@4.x(3)- reducer

    2024-07-11 03:46:01       25 阅读
  4. Linux 安装 docker-compose

    2024-07-11 03:46:01       20 阅读
  5. PostgreSQL

    2024-07-11 03:46:01       20 阅读
  6. Perl词法切分器:文本解析的瑞士军刀

    2024-07-11 03:46:01       18 阅读
  7. 解决Spring Boot中的安全漏洞与防护策略

    2024-07-11 03:46:01       20 阅读