spdLog的使用

spdLog的使用以下为收集到或者个人测试的内容,侵权删一.优点非常快使用自带的例子测试写log,利用次数/时钟周期衡量结果*******************************************************************************Singlethread,1,000,000iteration

大家好,又见面了,我是你们的朋友全栈君。

以下为收集到或者个人测试的内容,侵权删

一.优点

  • 非常快

    使用自带的例子测试写log,利用 次数/时钟周期 衡量结果
    *******************************************************************************
    Single thread, 1,000,000 iterations
    *******************************************************************************
    rotating_st...        1,464,366/sec
    daily_st...           1,377,742/sec
    null_st...            1,621,649/sec
    *******************************************************************************
    10 threads sharing same logger, 1,000,000 iterations
    *******************************************************************************
    rotating_mt...        1,165,635/sec
    daily_mt...           1,151,680/sec
    null_mt...            1,512,478/sec
    *******************************************************************************
    async logging.. 10 threads sharing same logger, 1,000,000 iterations
    *******************************************************************************
    as...                 3,901,457/sec
    as...                 6,977,551/sec
    as...                 7,005,095/sec

  • 只包含头文件
     (spdlog/spdlog.h —> spdlog , spdlog/fmt/bundled/format.h —> pattern_formatter)
  • 无需依赖第三方库
  • 支持跨平台 – Linux / Windows on 32/64 bits
  • 支持多线程

    单线程和多线程主要在锁的定义上不一样
    typedefrotating_file_sink<std::mutex> rotating_file_sink_mt;
    typedefrotating_file_sink<details::null_mutex>rotating_file_sink_st;
    其中 details::null_mutex 定义为:
    structnull_mutex
    {
        voidlock() {}
        voidunlock() {}
        booltry_lock()
        {
            returntrue;
        }
    };

  • 可对日志文件进行循环输出
     (指的是可以用 rotating_file_sink结构在 log_1,log_2,log_3 等几个文件中循环迭代,在不产生新的文件的情况下更新后面的文件)

    // Rotate files:
    // log.txt -> log.1.txt
    // log.1.txt -> log2.txt
    // log.2.txt -> log3.txt
    // log.3.txt -> delete

  • 可每日生成日志文件
    daily_file_sink 每天定时产生文件日志
  • 支持控制台日志输出
  • 可选的异步日志
  • 支持日志输出级别
  • 可自定义日志格式

二.基本使用

1.直接打印日志到console

auto console1 = spd::stdout_logger_mt("console1");
console1->error("Some error message with arg{}..", 1);
 
//console2 的module 名字不可以和以前的重复,创建的日志名字为 basic_log
auto console2 = spd::basic_logger_mt("basic_logger","./basic_log");
console2->info("Some log message");
 
//通过module名字获取到对应的log指针
spd::get("console2")->info("get console by name");
 
//设置日志等级
spd::set_level(spd::level::info);//Set global log level to info
console1->debug("This message shold not be displayed!");
console1->set_level(spd::level::debug);// Set specific logger's log level
console1->debug("This message shold be displayed..");

2.每天更新一个log文件(带秒数)

//创建文件名类似于: daily_log_2018-01-17_10-27.txt,如果程序不退出的话,就是每天2:30 am创建新的文件       
auto console3 =  spd::daily_logger_mt("daily_logger","./daily_log", 2, 30);
console3->flush_on(spd::level::debug);
console3->info("test daily info");
console3->error("test daily error")

        如果想在文件名里只关心天数,可以使用这个,这样的好处是,同一天多次运行一个程序,可以把log写到同一个文件里面去,测试了不会覆盖以前的内容

//创建文件名类似于: log_2018-01-17.txt
typedefspdlog::sinks::daily_file_sink<std::mutex, spdlog::sinks::dateonly_daily_file_name_calculator> dateonly_daily_file_sink_mt;
auto m_logger = spdlog::create<dateonly_daily_file_sink_mt>("logger","log","txt", 0, 0);
m_logger->info("test daily info");
m_logger->error("test daily error");

3.日志太多的时候,当前文件重命名_1,_2,_3.再写新的文件

//日志文件名为
//-rw-rw-r-- 1 ski ski    962 Jan 17 10:48 mylogfile_log.1.txt
//-rw-rw-r-- 1 ski ski    962 Jan 17 10:48 mylogfile_log.2.txt
//-rw-rw-r-- 1 ski ski    962 Jan 17 10:48 mylogfile_log.3.txt
//-rw-rw-r-- 1 ski ski    370 Jan 17 10:48 mylogfile_log.txt
 
auto rotating_logger = spd::rotating_logger_mt("rotate_log","./mylogfile_log", 1024, 3);
for (int i = 0; i < 1000; ++i)
    rotating_logger->info("{} * {} equals {:>10}", i, i, i*i);

4.flush_on命令

//遇到错误及以上级别会立马将缓存的buffer写到文件中,底层调用是std::fflush(_fd)
m_logger->flush_on(spd::level::err);

5.关闭所有的log handler

// Release and close all loggers 把所有的log对象智能指针放置到unordered_map中去,然后调用clear函数
spdlog::drop_all();

 三.源码阅读

spdlog支持多线程的,想看看其中是怎么控制同步的,实现多线程的一个接口:
auto rotating_logger = spd::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3);

点进去:

inline std::shared_ptr<spdlog::logger> spdlog::rotating_logger_mt(const std::string& logger_name, const filename_t& filename, size_t max_file_size, size_t max_files)
{
    return create<spdlog::sinks::rotating_file_sink_mt>(logger_name, filename, max_file_size, max_files);
}

继续:

typedef rotating_file_sink<std::mutex> rotating_file_sink_mt;
typedef rotating_file_sink<details::null_mutex>rotating_file_sink_st;

所有的sinks类都是继承sinks类的,这里是从rotating_file_sink->base_sink->sink继承而来的。

template<class Mutex>
class rotating_file_sink SPDLOG_FINAL : public base_sink < Mutex >

看看base_sinks类中的两个关键log函数:

template<class Mutex>
class base_sink:public sink
{
    void log(const details::log_msg& msg) SPDLOG_FINAL override
    {
        std::lock_guard<Mutex> lock(_mutex);
        _sink_it(msg);
    }
    void flush() SPDLOG_FINAL override
    {
        std::lock_guard<Mutex> lock(_mutex);
        _flush();
    }
在这里是根据锁的类型不同而实现多线程和单线程的区别,多线程的锁可以使用正常的锁机制来使用,那么,单线程的使用呢? 开始查看details::null_mutex的定义:
struct null_mutex
{
    void lock() {}
    void unlock() {}
    bool try_lock()
    {
        return true;
    }
};

其实,他是使用了一个类去模拟锁的函数,但是里面什么也不做,这样就可以与多线程情况下使用同样的代码了,提升了代码效率。值得借鉴


其他:

参考网址:

1.spdLog官网

2.spdLog源码阅读

 主要包括三页内容:

        sink介绍(base_sink, rotating_file_sink,另外还有 daily_file_sink)

        sink创建和使用(稍微介绍了下单例模式)

        log_msg的原理介绍(缓冲区存储日志内容)

3.spdLog使用example

        这是spdLog自带的一个example,教你如何使用sink去写log

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/152329.html原文链接:https://javaforall.net

(0)
上一篇 2022年6月23日 下午2:16
下一篇 2022年6月23日 下午2:16


相关推荐

  • PHP json_decode 出错

    PHP json_decode 出错json串中有时会包含json_decode解析不了的字符串,可以使用下面封装好的来处理。下载地址:Services_JSON

    2022年7月17日
    15
  • redis主从架构锁失效问题(主从)

    一、准备1、修改pidfile和端口2、关闭RDB持久化修改持久化文件的保存位置3、启动Redisredis-server/etc/redis.conf4、使用客户端连接Redisredis-cli二、主从复制(读写分离)redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构.可

    2022年4月10日
    196
  • android之SQLite数据库insert操作

    原型:long android.database.sqlite.SQLiteDatabase.insert(String table, String nullColumnHack, ContentValues values) 参数介绍:table: 要插入数据的表的名称nullColumnHack:当values参数为空或者里面没有内容的时候,我们insert是会失败的(底

    2022年3月10日
    251
  • windows server2016搭建ftp服务器_搭建网站的服务器

    windows server2016搭建ftp服务器_搭建网站的服务器WindowsServer2016系统中,快速搭建FTP服务器,作为文件服务器,下面分三步说明:安装IIS和FTP服务 配置FTP服务 测试FTP一、安装IIS和FTP服务首先点击开始菜单,进入找到服务器管理器,点击打开。进入后,找到管理菜单,点击添加角色和功能。进入服务器系统打开“服务器管理器”,点击“添加角色和功能”进入角色添加向导,一直点击下一步按钮到服务…

    2025年10月28日
    7
  • 宝塔开启nginx防火墙导致nginx无法启动

    宝塔开启nginx防火墙导致nginx无法启动问题现象 宝塔搭建的 nginx 无法启动 nginx t 报错 nginx theconfigura etc nginx nginx confsyntaxis configuratio etc nginx nginx conftestfail 日志中没有任何报错 nginx 命令启动后也没有报错 端口无法监听 是由于刚开启了 nginx 防火墙 但是由于用户 nginx 版本较低 无法开启将 www server panel vhost ng

    2026年3月17日
    2
  • 快速为已有项目集成后台管理系统

    快速为已有项目集成后台管理系统添加 5 张表 管理员表 sp admin API 日志表 sp apilog 项目配置表 sp cfg 角色表 sp role 角色权限表 sp role permission 系统角色表 droptableife role CREATETABLE sp role id bigint 20 NOTNULLAUTO INCREMENTCOM 角色 id 主键 自增 name varchar 20 NOTNULLCOMME

    2026年3月19日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号