C++11日志之spdlog

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: C++11日志之spdlog

c++日志工具spdlog


spdlog日志是纯头文件,使用起来比较方便。使用时只需要简单的初始化即可,这里对其初始化做了一个简单的封装,这样使用起来更加方便。


封装类代码


头文件


cspdlog.h

#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


源文件


cspdlog.cpp

#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); //设置终端界面输出级别
  CSpdlog::GetInstance()->SetFileLogLevel(spdlog::level::warn);     //设置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

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
3月前
|
缓存 Linux 编译器
【C++】CentOS环境搭建-安装log4cplus日志组件包及报错解决方案
通过上述步骤,您应该能够在CentOS环境中成功安装并使用log4cplus日志组件。面对任何安装或使用过程中出现的问题,仔细检查错误信息,对照提供的解决方案进行调整,通常都能找到合适的解决之道。log4cplus的强大功能将为您的项目提供灵活、高效的日志管理方案,助力软件开发与维护。
84 0
|
4月前
|
存储 运维 监控
超级好用的C++实用库之日志类
超级好用的C++实用库之日志类
58 0
|
5月前
|
Java 编译器 数据库
异步日志方案——spdlog
异步日志方案——spdlog
|
7月前
spdlog 日志库部分源码说明——让你可以自定义的指定自动切换日志时间
spdlog 日志库部分源码说明——让你可以自定义的指定自动切换日志时间
176 7
|
7月前
Liunx怎么安装spdlog(这是用来管理日志部分)
Liunx怎么安装spdlog(这是用来管理日志部分)
139 7
|
7月前
|
C++
spdlog 日志库部分源码说明——日志格式设定,DIY你自己喜欢的调试信息,你能调试的远比你想象的还要丰富
spdlog 日志库部分源码说明——日志格式设定,DIY你自己喜欢的调试信息,你能调试的远比你想象的还要丰富
402 6
|
7月前
|
监控 C++
c++实战篇(二)——基于自旋锁实现的日志服务模块
c++实战篇(二)——基于自旋锁实现的日志服务模块
|
8月前
|
C++
glog --- C++日志库
glog --- C++日志库
|
2月前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
439 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
23天前
|
监控 安全 Apache
什么是Apache日志?为什么Apache日志分析很重要?
Apache是全球广泛使用的Web服务器软件,支持超过30%的活跃网站。它通过接收和处理HTTP请求,与后端服务器通信,返回响应并记录日志,确保网页请求的快速准确处理。Apache日志分为访问日志和错误日志,对提升用户体验、保障安全及优化性能至关重要。EventLog Analyzer等工具可有效管理和分析这些日志,增强Web服务的安全性和可靠性。