Cpp(十二) log日志基本使用spdlog

2021-03-02 15:15:39 浏览数 (1)

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

将spdlog源码的头文件拷贝至include目录下

代码语言:javascript复制
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包括sinklogger两个部分

#4.1 什么是Sink

sink可以认为是一个操作文件的句柄,一个sink对应一个文件

  1. 日志按等级分割
  • 创建多个sink,每个sink对应一个等级
代码语言:javascript复制
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);
  1. 日志按时间分割
  • 每个sink,设置分割的时间
代码语言:javascript复制
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

一个logger可以对应多个sink

代码语言:javascript复制
// 将多个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_));
  1. 日志输出格式
代码语言:javascript复制
this->logger_->set_pattern("[%l] [%Y-%m-%d %H:%M:%S,%e] [Process:%P] - %v");

详细参考官方文档: https://github.com/gabime/spdlog/wiki/3.-Custom-formatting

0 人点赞