spdlog 使用学习笔记

发布时间 2023-09-08 18:16:05作者: BryceAi

spdlog使用学习笔记


部分内容参考了《spdlog使用_CSDN》这篇文章。

1. spdlog简介

github地址:https://github.com/gabime/spdlog

spdlog是一个C++的日志管理工具库。

2. spdlog的安装

2.1. 使用包管理器安装

  • Debian: sudo apt install libspdlog-dev
  • Homebrew: brew install spdlog
  • MacPorts: sudo port install spdlog
  • FreeBSD: pkg install spdlog
  • Fedora: dnf install spdlog
  • Gentoo: emerge dev-libs/spdlog
  • Arch Linux: pacman -S spdlog
  • openSUSE: sudo zypper in spdlog-devel
  • vcpkg: vcpkg install spdlog
  • conan: spdlog/[>=1.4.1]
  • conda: conda install -c conda-forge spdlog
  • build2: depends: spdlog ^1.8.2

2.2. 使用源码安装

$ git clone https://github.com/gabime/spdlog.git
$ cd spdlog && mkdir build && cd build
$ cmake .. && make -j

2.3。 仅使用头文件

spdlog/include目录下的文件拷贝到你的项目中即可。

3. 相关概念

3.1. level_enum

日志级别,定义如下:

enum class level_enum
{
    trace,
    debug,
    info,
    warn,
    err,
    critical,
    off,
};

3.2. sink

日志记录器槽,用于设置日志的输出目的地,如控制台、文件等。

常用函数:

virtual void log(const details::log_msg &msg) = 0; // 记录日志,有logger自动调用
virtual void flush() = 0;                       // 刷新日志
virtual void set_pattern(const std::string &pattern) = 0;   // 设置日志格式
virtual void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) = 0;  // 设置日志格式
void set_level(level::level_enum log_level);    // 设置输出日志的最低级别
level::level_enum level() const;            // 获取日志级别
bool should_log(level::level_enum msg_level) const; // 判断是否需要记录日志

3.3. logger

日志记录器,用于记录日志。一个logger对象中存储有多个sink,当调用logger的日志输出函数时,logger会调用自身存储的所有sink对象的log(log_msg) 函数进行输出。与自带的sink对应,spdlog也自带了几种logger。logger类主要使用的函数包括:

template<typename T>
void trace(const T &msg) // 记录trace级别的日志
{
    log(level::trace, msg);
}

template<typename T>
void debug(const T &msg) // 记录debug级别的日志
{
    log(level::debug, msg);
}

template<typename T>
void info(const T &msg)
{
    log(level::info, msg);
}

template<typename T>
void warn(const T &msg)
{
    log(level::warn, msg);
}

template<typename T>
void error(const T &msg)
{
    log(level::err, msg);
}

template<typename T>
void critical(const T &msg)
{
    log(level::critical, msg);
}


// return true logging is enabled for the given level.
bool should_log(level::level_enum msg_level) const
{
    return msg_level >= level_.load(std::memory_order_relaxed);
}

// return true if backtrace logging is enabled.
bool should_backtrace() const
{
    return tracer_.enabled();
}

void set_level(level::level_enum log_level); // 设置日志级别

level::level_enum level() const;

const std::string &name() const;

// set formatting for the sinks in this logger.
// each sink will get a separate instance of the formatter object.
void set_formatter(std::unique_ptr<formatter> f);

// set formatting for the sinks in this logger.
// equivalent to
//     set_formatter(make_unique<pattern_formatter>(pattern, time_type))
// Note: each sink will get a new instance of a formatter object, replacing the old one.
void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local);

// backtrace support.
// efficiently store all debug/trace messages in a circular buffer until needed for debugging.
void enable_backtrace(size_t n_messages);
void disable_backtrace();
void dump_backtrace();

// flush functions
void flush();
void flush_on(level::level_enum log_level);
level::level_enum flush_level() const;

// sinks
const std::vector<sink_ptr> &sinks() const;

std::vector<sink_ptr> &sinks();

// error handler
void set_error_handler(err_handler);

// create new logger with same sinks and configuration.
virtual std::shared_ptr<logger> clone(std::string logger_name);

4. spdlog的使用

4.1. 基本使用

#include "spdlog/spdlog.h"

int main() 
{
    spdlog::info("Welcome to spdlog!");
    spdlog::error("Some error message with arg: {}", 1);
    
    spdlog::warn("Easy padding in numbers like {:08d}", 12);
    spdlog::critical("Support for int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}", 42);
    spdlog::info("Support for floats {:03.2f}", 1.23456);
    spdlog::info("Positional args are {1} {0}..", "too", "supported");
    spdlog::info("{:<30}", "left aligned");
    
    spdlog::set_level(spdlog::level::debug); // Set global log level to debug
    spdlog::debug("This message should be displayed..");    
    
    // change log pattern
    spdlog::set_pattern("[%H:%M:%S %z] [%n] [%^---%L---%$] [thread %t] %v");
    
    // Compile time log levels
    // define SPDLOG_ACTIVE_LEVEL to desired level
    SPDLOG_TRACE("Some trace message with param {}", 42);
    SPDLOG_DEBUG("Some debug message");
}

编译后会输出的对应内容。

4.2. 输出日志到文件

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

int main() 
{
    // Create basic file logger (not rotated)
    //文件保存在logs/basic-log.txt
    auto my_logger = spdlog::basic_logger_mt("basic_logger", "logs/basic-log.txt");
    my_logger->info("Some log message");
    //my_logger是一个指向logger对象的智能指针,可以直接使用->访问logger的成员函数
}