Cpp日志spdlog
#1 环境
代码语言:javascript复制macOS 10.15.5
spdlog
#2 需求分析
- 日志按等级分到不同的文件
- 日志按时间分割
#3 使用
#3.1 工程结构
代码语言:javascript复制.
├── CMakeLists.txt
├── cmake-build-debug
├── include
│ └── spdlog
├── log.hpp
└── main.cpp
#3.2 CMakeLists.txt
代码语言:javascript复制cmake_minimum_required(VERSION 3.17)
project(my_spdlog)
set(CMAKE_CXX_STANDARD 14)
include_directories(include) # spdlog路径
add_executable(my_spdlog main.cpp)
#3.3 include
代码语言:javascript复制将spdlog源码的头文件拷贝至
include
目录下
https://gitee.com/Coxhuang/spdlog/tree/v1.x/include/spdlog
#3.4 log.hpp
代码语言:javascript复制#ifndef MY_SPDLOG_LOG_HPP
#define MY_SPDLOG_LOG_HPP
#include <iostream>
#include <memory>
#include "spdlog/spdlog.h"
#include "spdlog/async.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"
#include "spdlog/sinks/daily_file_sink.h"
#include "spdlog/sinks/basic_file_sink.h"
class MyLog {
public:
static MyLog &instance() {
static MyLog m_instance;
return m_instance;
}
auto get_logger() const {
return this->logger_;
}
private:
MyLog() {
this->init();
}
~MyLog() {
spdlog::drop_all(); // 释放所有logger
}
private:
void init() {
std::cout << "log init " << std::endl;
this->init_file();
this->init_logger();
}
void init_file() {
this->log_root_path = "/var/log/";
this->info_file_path = "info.log";
this->error_file_path = "erro.log";
this->rotation_h = 5; // 分割时间
this->rotation_m = 59;
}
void init_logger() {
this->info_sink_ = std::make_shared<spdlog::sinks::daily_file_sink_mt>(
this->log_root_path this->info_file_path, this->rotation_h, this->rotation_m);
this->error_sink_ = std::make_shared<spdlog::sinks::daily_file_sink_mt>(
this->log_root_path this->error_file_path, this->rotation_h, this->rotation_m);
this->console_sink_ = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
this->info_sink_->set_level(spdlog::level::info); // debug< info< warn< error< critical 日志信息低于设置的级别时, 不予显示
this->error_sink_->set_level(spdlog::level::err);
this->console_sink_->set_level(spdlog::level::debug);
this->sinks_.push_back(this->info_sink_); // info
this->sinks_.push_back(this->error_sink_); // error
this->sinks_.push_back(this->console_sink_); // console
this->logger_ = std::make_shared<spdlog::logger>("log_demo", begin(this->sinks_), end(this->sinks_));
this->logger_->set_pattern("[%l] [%Y-%m-%d %H:%M:%S,%e] [Process:%P] - %v");
this->logger_->flush_on(spdlog::level::info); // 设置当触发 info 或更严重的错误时立刻刷新日志到 disk
spdlog::register_logger(this->logger_); // 注册logger
spdlog::flush_every(std::chrono::seconds(10)); // 每隔10秒刷新一次日志
}
private:
std::shared_ptr <spdlog::logger> logger_;
std::shared_ptr <spdlog::sinks::daily_file_sink_mt> info_sink_; // info
std::shared_ptr <spdlog::sinks::daily_file_sink_mt> error_sink_; // error
std::shared_ptr <spdlog::sinks::stdout_color_sink_mt> console_sink_; // console
std::vector <spdlog::sink_ptr> sinks_;
std::string log_root_path;
std::string error_file_path;
std::string info_file_path;
short int rotation_h{};
short int rotation_m{};
}; // MyLog
#define ilog MyLog::instance().get_logger()
#endif //MY_SPDLOG_LOG_HPP
#3.5 main.cpp
代码语言:javascript复制#include <iostream>
#include "log.hpp"
int main() {
int a = 1;
ilog->info("info:{}",a);
return 0;
}
#4 Spdlog
Spdlog包括
sink
和logger
两个部分
#4.1 什么是Sink
sink
可以认为是一个操作文件的句柄,一个sink
对应一个文件
- 日志按等级分割
- 创建多个
sink
,每个sink
对应一个等级
this->info_sink_ = std::make_shared<spdlog::sinks::daily_file_sink_mt>(this->log_root_path this->info_file_path, this->rotation_h, this->rotation_m);
this->error_sink_ = std::make_shared<spdlog::sinks::daily_file_sink_mt>(this->log_root_path this->error_file_path, this->rotation_h, this->rotation_m);
this->console_sink_ = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
this->info_sink_->set_level(spdlog::level::info); // debug< info< warn< error< critical 日志信息低于设置的级别时, 不予显示
this->error_sink_->set_level(spdlog::level::err);
this->console_sink_->set_level(spdlog::level::debug);
- 日志按时间分割
- 每个
sink
,设置分割的时间
this->info_sink_ = std::make_shared<spdlog::sinks::daily_file_sink_mt>(this->log_root_path this->info_file_path, this->rotation_h, this->rotation_m);
spdlog::sinks::daily_file_sink_mt: 创建一个可以按时间分割的
sink
#4.2 什么是Logger
代码语言:javascript复制一个
logger
可以对应多个sink
// 将多个sink,加入logger
this->sinks_.push_back(this->info_sink_); // info
this->sinks_.push_back(this->error_sink_); // error
this->sinks_.push_back(this->console_sink_); // console
this->logger_ = std::make_shared<spdlog::logger>("log_demo", begin(this->sinks_), end(this->sinks_));
- 日志输出格式
this->logger_->set_pattern("[%l] [%Y-%m-%d %H:%M:%S,%e] [Process:%P] - %v");
详细参考官方文档: https://github.com/gabime/spdlog/wiki/3.-Custom-formatting