一个简单的spdlog使用示例

这篇具有很好参考价值的文章主要介绍了一个简单的spdlog使用示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录
  • 引用源码
  • 封装Log头文件
  • 使用方法

spdlog是一个开源、跨平台、无依赖、只有头文件的C++11日志库,网上介绍的文章有很多这里就不过多的介绍了,GitHub链接:https://github.com/gabime/spdlog。

引用源码

先下载spdlog的源码,将源码的include文件夹复制到自己的项目文件夹下:
一个简单的spdlog使用示例

然后在项目属性中包含include目录,如下图所示:
一个简单的spdlog使用示例

封装Log头文件

一般的项目对日志要求都不高,主要是要求日志线程安全、异步写入文件、每天生成新日志、支持日志回调显示,spdlog稍微配置一下即可。
把spdlog相关的配置全放到Log.h文件中,封装成Log头文件有两个好处:

  • 可以随时替换后台日志实现
  • 对外只用暴露一个头文件

Log头文件的代码如下:

#pragma once

#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/stopwatch.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/callback_sink.h"
#include <iostream>

void init_spdlog()
{
    //异步日志,具有8k个项目和1个后台线程的队列
    spdlog::init_thread_pool(8192, 1);
    //标准控制台输出
    auto stdout_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt >();
    stdout_sink->set_level(spdlog::level::debug);
    //日志文件输出,0点0分创建新日志
    auto file_sink = std::make_shared<spdlog::sinks::daily_file_sink_mt>("logs/log.txt", 0, 0);
    file_sink->set_level(spdlog::level::info);
    //日志回调
    auto callback_sink = std::make_shared<spdlog::sinks::callback_sink_mt>([](const spdlog::details::log_msg& msg)
        {
            //日志记录器名称
            std::string name(msg.logger_name.data(), 0, msg.logger_name.size());
            //日志消息
            std::string str(msg.payload.data(), 0, msg.payload.size());
            //日志时间
            std::time_t now_c = std::chrono::system_clock::to_time_t(msg.time);

            //回调的处理逻辑自己根据项目情况定义,比如实时显示到UI、保存到数据库等等
            
            //.... 回调处理逻辑的示例
            //std::tm localTime;
            //localtime_s(&localTime, &now_c);
            //char timeStr[50];
            //std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &localTime);
            //// 获取毫秒数
            //auto duration = msg.time.time_since_epoch();
            //auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count() % 1000;
            //std::cout << timeStr << "." << std::setfill('0') << std::setw(3) << milliseconds << " " ;
            //std::cout << to_string_view(msg.level).data() << " " << str << std::endl << std::endl << std::flush;

        });
    callback_sink->set_level(spdlog::level::info);

    std::vector<spdlog::sink_ptr> sinks{ stdout_sink, file_sink,callback_sink };
    auto log = std::make_shared<spdlog::async_logger>("logger", sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);

    //设置日志记录级别,您需要用 %^ 和 %$  括上想要彩色的部分
    log->set_level(spdlog::level::trace);
    //设置格式
    //参考 https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
    //[%Y-%m-%d %H:%M:%S.%e] 时间
    //[%l] 日志级别
    //[%t] 线程
    //[%s] 文件
    //[%#] 行号
    //[%!] 函数
    //[%v] 实际文本
    log->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %^[%l]%$ [%t] [%s %!:%#] %v");
    //设置当出发 err 或更严重的错误时立刻刷新日志到  disk
    log->flush_on(spdlog::level::err);
    //3秒刷新一次队列
    spdlog::flush_every(std::chrono::seconds(3));
    spdlog::set_default_logger(log);
}

//单个日志记录器
std::shared_ptr<spdlog::logger>  get_async_file_logger(std::string name)
{
    auto log = spdlog::get(name);
    if (!log)
    {
        //指针为空,则创建日志记录器,
        log = spdlog::daily_logger_mt<spdlog::async_factory>(name, "logs/" + name + "/log.txt");
        log->set_level(spdlog::level::trace);
        log->flush_on(spdlog::level::err);
        log->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %^[%l]%$ [%t] [%s %!:%#] %v");
        //记录器是自动注册的,不需要手动注册  spdlog::register_logger(name);
    }
    return log;
}

#define INITLOG()     init_spdlog()


#define TRACE(...)     SPDLOG_TRACE(__VA_ARGS__)
#define DEBUG(...)     SPDLOG_DEBUG(__VA_ARGS__)
#define INFO(...)      SPDLOG_INFO(__VA_ARGS__)
#define WARN(...)      SPDLOG_WARN(__VA_ARGS__)
#define ERROR(...)     SPDLOG_ERROR(__VA_ARGS__)
#define CRITICAL(...)  SPDLOG_CRITICAL(__VA_ARGS__)

//单个日志文件
#define GETLOG(LOG_NAME) get_async_file_logger(LOG_NAME)

#define LOGGER_TRACE(logger,...)     SPDLOG_LOGGER_TRACE(logger,__VA_ARGS__)
#define LOGGER_DEBUG(logger,...)     SPDLOG_LOGGER_DEBUG(logger,__VA_ARGS__)
#define LOGGER_INFO(logger,...)      SPDLOG_LOGGER_INFO(logger,__VA_ARGS__)
#define LOGGER_WARN(logger,...)      SPDLOG_LOGGER_WARN(logger,__VA_ARGS__)
#define LOGGER_ERROR(logger,...)     SPDLOG_LOGGER_ERROR(logger,__VA_ARGS__)
#define LOGGER_CRITICAL(logger,...)  SPDLOG_LOGGER_CRITICAL(logger,__VA_ARGS__)

//时间统计宏
#define LOGSW() spdlog::stopwatch()

上面的代码是用于初始化和配置spdlog库的日志记录器的代码。主要包括以下几个部分:

  • init_spdlog()函数用于初始化spdlog库的配置。该函数创建了一个包含控制台、文件和回调三种sink的日志记录器,并设置将其设置为默认记录器。
  • get_async_file_logger()函数获取一个单独的异步文件日志记录器,主要用于记录多线程日志,一般情况下用的比较少。
  • 用于简化日志记录的操作一些宏,spdlog自带的有日志宏,这里只是简化一下并做隔离,实际上是对spdlog库的相应函数进行了封装。
  • 定义了一个LOGSW()宏,用于方便地创建一个时间统计器,使用时不需要过多的关注统计类本身。

使用方法

使用方法如下:

#include "Log.h"
#include <thread>
#include <chrono>
#include <iostream>

int main()
{
    INITLOG("path");

    //单个日志
    auto log1= GETLOG("Test1");
    auto log2= GETLOG("Test1");
    //原始调用方式
    //SPDLOG_LOGGER_INFO(log1, "123");
    LOGGER_INFO(log2, "123");

    auto sw = LOGSW();
    // 延时2秒
    std::this_thread::sleep_for(std::chrono::seconds(2)); 
    INFO("Elapsed {0} {1}","时间", sw);
    WARN("Elapsed {0} {1}", "时间", sw);
    //原始调用方式
    //SPDLOG_INFO("TEST");
    INFO("TEST");
}

最后生成的日志文件如下:
一个简单的spdlog使用示例
一个简单的spdlog使用示例文章来源地址https://www.toymoban.com/news/detail-673069.html

到了这里,关于一个简单的spdlog使用示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 01、spdlog源码阅读——registry注册表

    注册表具有唯一标识,用于管理多个日志

    2024年02月15日
    浏览(34)
  • 一个简单的转账场景示例带你了解并发安全?

    本文转帐场景主要参考来自于极客时间 王老师的 《Java 并发编程实战》 一个简单的转账场景示例带你了解并发安全? 例如如银行业务里面的转账操作,账户 A 减少 100 元,账户 B 增加 100 元。 我们声明了个账户类:Account,该类有一个成员变量余额:balance,还有一个用于转账

    2024年01月22日
    浏览(37)
  • 不同微服务之间如何实现远程调用?一个简单示例告诉你

    目录 1、服务拆分原则  2、服务拆分示例 2.1、初始化数据库 2.2、导入demo工程 2.3、测试 3、实现远程调用 3.1、需求 3.2、注册RestTemplate 3.3、实现远程调用 4、提供者与消费者 5、代码免费分享 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习

    2024年04月27日
    浏览(27)
  • Go 语言实现归并排序算法的简单示例(附上源码)

    以下是使用 Go 语言实现归并排序算法的简单示例: 在这个例子中, mergeSort 函数接收一个整数切片,使用递归的方式进行归并排序。 merge 函数用于合并两个已排序的切片。在 main 函数中,我们定义了一个示例数组,调用 mergeSort 函数对其进行排序,并输出结果。 归并排序算

    2024年01月21日
    浏览(29)
  • Python中的if语句:一个简单的正负数判断示例

    本文介绍了如何在Python中使用 if 语句编写一个简单的程序,用于判断用户输入数字的正负性。示例代码易于理解,适用于初学者学习。 1. 介绍 if 语句是编程中非常基本和重要的一个概念,它让程序根据条件执行特定的代码块。在Python中, if 语句的语法非常简单,易于学习。

    2024年02月09日
    浏览(29)
  • Solon Web 开发:三、一个简单的 Web 模板项目(或示例)

    演示 web 程序的常用能力: 控制器、请求参数、参数校验、跳转 过滤器、全局异常处理 静态文件 动态模板 动态模板公共变量及控制器基类 日志 Json 渲染格式控制 模板下载: 打包成 jar ,可以自启动 helloworld_web_jar.zip (maven) helloworld_web_jar_gradle.zip (gradle) 打包成 war,需

    2024年02月12日
    浏览(34)
  • 轻量封装WebGPU渲染系统示例<11>- WebGP实现的简单PBR效果(源码)

    当前示例源码github地址: https://github.com/vilyLei/voxwebgpu/blob/main/src/voxgpu/sample/SimplePBRTest.ts 此示例渲染系统实现的特性: 1. 用户态与系统态隔离。          细节请见:引擎系统设计思路 - 用户态与系统态隔离-CSDN博客 2. 高频调用与低频调用隔离。 3. 面向用户的易用性封装。

    2024年02月06日
    浏览(27)
  • 【C++】开源:spdlog跨平台日志库配置使用

    😏 ★,° :.☆( ̄▽ ̄)/$: .°★ 😏 这篇文章主要介绍spdlog日志库配置使用。 无专精则不能成,无涉猎则不能通。——梁启超 欢迎来到我的博客,一起学习,共同进步。 喜欢的朋友可以关注一下,下次更新不迷路🥞 项目Github地址: https://github.com/gabime/spdlog Spdlog 是一个高性能

    2024年02月13日
    浏览(36)
  • Fast DDS入门五、在Windows平台创建一个简单的Fast DDS示例程序

    在这里,先建立一个IDL文件,然后通过使用Fast DDS-Gen生成程序生成这个简单示例程序。Fast DDS-Gen程序的编译安装请参考《Fast DDS入门二、Fast DDS在Windows平台的编译安装》,Fast DDS-Gen程序的使用请参考《Fast DDS入门四、Fast DDS-Gen使用介绍》。 (1)创建IDL文件 先建立一个单独的目

    2024年02月16日
    浏览(37)
  • vue3 实现简单计数器示例——一个html文件展示vue3的效果

    目的 :作为一个新手开发,我想使用 Vue 3 将代码封装在 HTML 文件中时,进行界面打开展示。 学了一个简单计数器界面展示,代码如下: 在 上述HTML 文件里,包含了文件头标题 title , 接着定义了一个内容 div id=\\\"app\\\" 而后定义了一个内容,包含标题和数字,以及两个按钮的 templa

    2024年01月18日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包