C++ 日志工具推薦之 Spdlog
作者:fensnote
spdlog日志是純頭文件,使用起來比較方便。使用時只需要簡單的初始化即可,這里對其初始化做了一個簡單的封裝,這樣使用起來更加方便。
本文轉(zhuǎn)載自微信公眾號「嵌入式技術(shù)筆記」,作者fensnote。轉(zhuǎn)載本文請聯(lián)系嵌入式技術(shù)筆記公眾號。
c++日志工具spdlog
spdlog日志是純頭文件,使用起來比較方便。使用時只需要簡單的初始化即可,這里對其初始化做了一個簡單的封裝,這樣使用起來更加方便。
輸出到console與輸出到文件的級別可以分開設(shè)置,并支持動態(tài)設(shè)置。
封裝類代碼
頭文件
- #ifndef _CSPDLOG_H_
- #define _CSPDLOG_H_
- #include "spdlog/spdlog.h"
- #include "spdlog/fmt/bin_to_hex.h"
- #include <memory>
- #include <string>
- class CSpdlog
- {
- protected:
- CSpdlog();
- ~CSpdlog();
- static CSpdlog *m_instance;
- public:
- static CSpdlog *GetInstance();
- void Init(const std::string & name,const std::string &logPath, std::size_t max_size=1048576, std::size_t max_file = 2);
- void SetConsoleLogLevel(spdlog::level::level_enum log_level);
- void SetFileLogLevel(spdlog::level::level_enum log_level);
- private:
- std::vector<spdlog::sink_ptr> m_sinks;
- std::shared_ptr<spdlog::logger> m_logger;
- };
- #endif
源文件
- #include "cspdlog.h"
- #include <cstdio>
- #include <iostream>
- #include "spdlog/sinks/stdout_color_sinks.h" // or "../stdout_sinks.h" if no color needed
- #include "spdlog/sinks/basic_file_sink.h"
- #include "spdlog/sinks/rotating_file_sink.h"
- CSpdlog::CSpdlog()
- {
- }
- CSpdlog::~CSpdlog()
- {
- }
- void CSpdlog::Init(const std::string & name, const std::string &log_path, std::size_t max_size, std::size_t max_file )
- {
- try
- {
- auto console_sink = std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
- console_sink->set_level(spdlog::level::debug);
- console_sink->set_pattern("%^[%Y-%m-%d %H:%M:%S:%e] [%n] [tid: %t] [%l] %v%$");
- std::string logFile = log_path + "/" + name + ".txt";
- //auto file_sink = std::make_shared<spdlog::sinks::basic_file_sink_mt>("logs/multisink.txt", false);
- auto file_sink = std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logFile, max_size, max_file);
- file_sink->set_pattern("[%Y-%m-%d %H:%M:%S:%e] [%n] [tid: %t] [%l] %v");
- file_sink->set_level(spdlog::level::warn);
- m_sinks.push_back(console_sink);
- m_sinks.push_back(file_sink);
- //spdlog::logger *logger = new spdlog::logger("multi_sink", {console_sink, file_sink});
- m_logger = std::make_shared<spdlog::logger>(name, begin( m_sinks ), end( m_sinks ));
- //spdlog::set_error_handler([](const std::string& msg){printf("*****Custom log error handler, %s*****%\n", msg.c_str());});
- //注冊到spdlog里
- spdlog::register_logger(m_logger);
- //m_logger->info("log init done.");
- m_logger->flush_on(spdlog::level::level_enum::warn);
- }
- catch (const spdlog::spdlog_ex &ex)
- {
- std::cout<<"Log initialization faild"<<ex.what()<<std::endl;
- }
- }
- void CSpdlog::SetConsoleLogLevel(spdlog::level::level_enum log_level)
- {
- m_logger->set_level(log_level);
- }
- void CSpdlog::SetFileLogLevel(spdlog::level::level_enum log_level)
- {
- m_sinks[1]->set_level(log_level);
- }
- CSpdlog* CSpdlog::m_instance = NULL;
- CSpdlog* CSpdlog::GetInstance()
- {
- if ( m_instance == NULL )
- {
- m_instance = new CSpdlog;
- }
- return m_instance;
- }
測試主程序
- #include <stdio.h>
- #include <unistd.h>
- #include <iostream>
- #include <cspdlog.h>
- using namespace std;
- int main()
- {
- CSpdlog::GetInstance()->Init("test","./log"); //初始化日志
- CSpdlog::GetInstance()->SetConsoleLogLevel(spdlog::level::debug); //設(shè)置終端界面輸出級別
- CSpdlog::GetInstance()->SetFileLogLevel(spdlog::level::warn); //設(shè)置log文件輸出級別
- auto logger = spdlog::get("test"); //獲取日志句柄
- logger->warn("test start.");
- int counter = 0;
- while(1)
- {
- logger->debug("debug msg, counter: {}",counter);
- logger->info("info msg, counter: {}",counter);
- logger->warn("warn msg, counter: {}",counter);
- logger->error("error msg, counter: {}",counter);
- logger->critical("critical msg, counter: {}",counter);
- logger->trace("trace msg, counter: {}",counter);
- usleep(500000);
- }
- return 0;
- }
編譯運行
我的通用Makefile
- #通用makefile
- #文件目錄
- DEBUG_DIR=.
- SRC_DIR=.
- INC_DIR=. ./spdlog
- SRC=$(wildcard $(SRC_DIR)/*.cpp ) #源文件
- OBJS=$(patsubst $(SRC_DIR)/%.cpp,$(DEBUG_DIR)/%.o,$(SRC))
- #目標文件名
- TARGET=test
- INSTALL_PATH ?= .
- #修改編譯器
- ARCH ?=
- CC=$(ARCH)gcc
- CPP=$(ARCH)g++
- AR=$(ARCH)ar
- STRIP=$(ARCH)strip
- CFLAGS += -Wall -std=c++11
- LDFLAGS += -lpthread
- CFLAGS += $(foreach dir,$(INC_DIR),-I$(dir))
- all:$(TARGET)
- $(TARGET): $(OBJS)
- $(CPP) $(OBJS) -o $@ $(CFLAGS) $(LDFLAGS)
- $(STRIP) $(TARGET)
- #cp $(TARGET) $(INSTALL_PATH)
- $(DEBUG_DIR)/%.o: $(SRC_DIR)/%.cpp
- $(CPP) $(CFLAGS) -c $< -o $@
- #@echo $(SRC)
- #@echo $(OBJS)
- clean:
- -rm $(OBJS) $(LIB_TARGET)
編譯
- make
- g++ -Wall -std=c++11 -I. -I./spdlog -c cspdlog.cpp -o cspdlog.o
- g++ -Wall -std=c++11 -I. -I./spdlog -c main.cpp -o main.o
- g++ ./cspdlog.o ./main.o -o test -Wall -std=c++11 -I. -I./spdlog
- strip test
運行
console輸出:
日志輸出
文件輸出:
- $cat log/test.txt
- [2021-08-17 15:30:59:526] [test] [tid: 20418] [warning] test start.
- [2021-08-17 15:30:59:527] [test] [tid: 20418] [warning] warn msg, counter: 0
- [2021-08-17 15:30:59:528] [test] [tid: 20418] [error] error msg, counter: 0
- [2021-08-17 15:30:59:529] [test] [tid: 20418] [critical] critical msg, counter: 0
- [2021-08-17 15:31:00:031] [test] [tid: 20418] [warning] warn msg, counter: 0
- [2021-08-17 15:31:00:032] [test] [tid: 20418] [error] error msg, counter: 0
- [2021-08-17 15:31:00:032] [test] [tid: 20418] [critical] critical msg, counter: 0
- [2021-08-17 15:31:00:533] [test] [tid: 20418] [warning] warn msg, counter: 0
- [2021-08-17 15:31:00:533] [test] [tid: 20418] [error] error msg, counter: 0
- [2021-08-17 15:31:00:534] [test] [tid: 20418] [critical] critical msg, counter: 0
測試源代碼以上傳碼云
地址:https://gitee.com/fensnote/demo_code/tree/master/cpp/spdlog
責任編輯:武曉燕
來源:
嵌入式技術(shù)筆記