spdlog简单封装 单例模式

spdlog使用说明: https://github.com/gabime/spdlog/wiki
常见的头开始部分

#ifdef _WIN32
#define __FILENAME__ (strrchr(__FILE__, '\\') ? (strrchr(__FILE__, '\\') + 1):__FILE__)
#else
#define __FILENAME__ (strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/') + 1):__FILE__)
#endif
 
//定义一个在日志后添加 文件名 函数名 行号 的宏定义
#ifndef suffix
#define suffix(msg)  std::string(msg).append("  <")\
        .append(__FILENAME__).append("> <").append(__func__)\
        .append("> <").append(std::to_string(__LINE__))\
        .append(">").c_str()
//#define suffix(msg)  std::string().append(" File:")\
//        .append(__FILENAME__).append("\", Func:\"").append(__func__)\
//        .append("()\", Line:\"").append(std::to_string(__LINE__)).append("\"").append(msg).c_str()
#endif

单例代码

1. 头文件logger.h

// logger.h
#ifndef LOGGER_H
#define LOGGER_H

#include "spdlog/spdlog.h"
#include "spdlog/sinks/rotating_file_sink.h"

// 日志的配置项
struct LogConfig {
    std::string level;
    std::string path;
    int64_t     size;
    int         count;
};

// 日志的单例模式
class Logger {
public:
    static Logger* getInstance() {
        static Logger instance;
        return &instance;
    }

	//c++14返回值可设置为auto
    std::shared_ptr<spdlog::logger> getLogger() {
        return loggerPtr;
    }

    void Init(const LogConfig& conf);

    std::string GetLogLevel();

    void SetLogLevel(const std::string& level);


private:
    Logger() = default;
    std::shared_ptr<spdlog::logger> loggerPtr;
};

// 日志相关操作的宏封装
#define INITLOG(conf)      Logger::getInstance()->Init(conf)
#define GETLOGLEVEL()      Logger::getInstance()->GetLogLevel()
#define SETLOGLEVEL(level) Logger::getInstance()->SetLogLevel(level)
#define BASELOG(logger, level, ...) (logger)->log(spdlog::source_loc{__FILE__, __LINE__, __func__}, level, __VA_ARGS__)
#define TRACELOG(...)     BASELOG(Logger::getInstance()->getLogger(), spdlog::level::trace, __VA_ARGS__)
#define DEBUGLOG(...)     BASELOG(Logger::getInstance()->getLogger(), spdlog::level::debug, __VA_ARGS__)
#define INFOLOG(...)      BASELOG(Logger::getInstance()->getLogger(), spdlog::level::info, __VA_ARGS__)
#define WARNLOG(...)      BASELOG(Logger::getInstance()->getLogger(), spdlog::level::warn, __VA_ARGS__)
#define ERRORLOG(...)     BASELOG(Logger::getInstance()->getLogger(), spdlog::level::err, __VA_ARGS__)
#define CRITICALLOG(...)  BASELOG(Logger::getInstance()->getLogger(), spdlog::level::critical, __VA_ARGS__)

#endif // LOGGER_H

2. 实现文件logger.cpp

// logger.cpp
#include "logger.h"

void Logger::Init(const LogConfig& conf) {
    //自定义的sink
    loggerPtr = spdlog::rotating_logger_mt("base_logger", conf.path.c_str(), conf.size, conf.count);
    //设置格式
    //参见文档 https://github.com/gabime/spdlog/wiki/3.-Custom-formatting
    //[%Y-%m-%d %H:%M:%S.%e] 时间
    //[%l] 日志级别
    //[%t] 线程
    //[%s] 文件
    //[%#] 行号
    //[%!] 函数
    //[%v] 实际文本
    loggerPtr->set_pattern("[%Y-%m-%d %H:%M:%S.%e] [%^%l%$] [thread %t] [%s %!:%#] %v");

    // 设置日志级别
    loggerPtr->set_level(spdlog::level::from_str(conf.level));
    // 设置刷新日志的日志级别,当出现level或更高级别日志时,立刻刷新日志到  disk
    loggerPtr->flush_on(spdlog::level::from_str(conf.level));
}

/*
 * trace 0
 * debug 1
 * info 2
 * warn 3
 * error 4
 * critical 5
 * off 6 (not use)
 */
std::string Logger::GetLogLevel() {
    auto level = loggerPtr->level();
    return spdlog::level::to_string_view(level).data();
}

void Logger::SetLogLevel(const std::string& log_level) {
    auto level = spdlog::level::from_str(log_level);
    if (level == spdlog::level::off) {
        WARNLOG("Given invalid log level {}", log_level);
    } else {
        loggerPtr->set_level(level);
        loggerPtr->flush_on(level);
    }
}

3. 测试文件logger_test.cpp

#include "logger.h"

int main()
{
	// 定义日志配置项
    LogConfig conf = {
        .level = "trace",
        .path  = "logger_test.log",
        .size  = 5 * 1024 * 1024,
        .count = 10,
    };
    INITLOG(conf);
    // 日志初始级别为trace
    TRACELOG("current log level is {}", GETLOGLEVEL());
    TRACELOG("this is trace log");
    DEBUGLOG("this is debug log");
    INFOLOG("this is info log");
    WARNLOG("this is warning log");
    ERRORLOG("this is a error log");
    CRITICALLOG("this is critical log");

	// 改为warning级别后,trace、debug、info级别日志不会输出了
    SETLOGLEVEL("warn");
    WARNLOG("after set log level to warning");
    TRACELOG("this is trace log");
    DEBUGLOG("this is debug log");
    INFOLOG("this is info log");
    WARNLOG("this is warning log");
    ERRORLOG("this is a error log");
    CRITICALLOG("this is critical log");

    return 0;
}

4. 测试结果

# 编译
g++ -std=c++11 -g logger_test.cpp logger.cpp -o logger_test
# 运行
./logger_test
# 查看结果
cat logger_test.log

[2023-01-15 06:40:21.447] [trace] [thread 1988] [logger_test.cpp main:16] current log level is trace
[2023-01-15 06:40:21.447] [trace] [thread 1988] [logger_test.cpp main:17] this is trace log
[2023-01-15 06:40:21.447] [debug] [thread 1988] [logger_test.cpp main:18] this is debug log
[2023-01-15 06:40:21.447] [info] [thread 1988] [logger_test.cpp main:19] this is info log
[2023-01-15 06:40:21.447] [warning] [thread 1988] [logger_test.cpp main:20] this is warning log
[2023-01-15 06:40:21.447] [error] [thread 1988] [logger_test.cpp main:21] this is a error log
[2023-01-15 06:40:21.447] [critical] [thread 1988] [logger_test.cpp main:22] this is critical log
[2023-01-15 06:40:21.447] [warning] [thread 1988] [logger_test.cpp main:25] after set log level to warning
# 改为warning级别后,trace、debug、info级别日志不会输出了
[2023-01-15 06:40:21.447] [warning] [thread 1988] [logger_test.cpp main:29] this is warning log
[2023-01-15 06:40:21.447] [error] [thread 1988] [logger_test.cpp main:30] this is a error log
[2023-01-15 06:40:21.447] [critical] [thread 1988] [logger_test.cpp main:31] this is critical log
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值