当前位置: 首页 > news >正文

C++开源库glog使用封装--自定义日志输出格式,设置日志保留时间

glog下载和编译

  • glog开源地址

https://github.com/google/glog

  • glog静态库编译
cd /home/wangz/3rdParty/hldglog/glogmkdir out 
mkdir build && cd buildcmake ..  -DCMAKE_INSTALL_PREFIX=../out -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF
本文选择的glog版本为glog-0.7.0

Hldglog类封装

#ifndef HLD_GLOG_H
#define HLD_GLOG_H#define GLOG_USE_GLOG_EXPORT
#include <glog/logging.h>#define HLD_LOG_INFO LOG(INFO)
#define HLD_LOG_WARNING LOG(WARNING)
#define HLD_LOG_ERROR LOG(ERROR)
// #define LOG_FATAL LOG(FATAL) FATAL消息会终止程序(在记录消息之后),禁用class Hldglog
{
public:static Hldglog *InitGlog(const char *argv, std::string logPath);private:Hldglog() = default;virtual ~Hldglog();Hldglog(const Hldglog &) = delete;Hldglog &operator=(const Hldglog &) = delete;Hldglog(Hldglog &&) = delete;Hldglog &operator=(Hldglog &&) = delete;private:static void CustomePrefixFormatter(std::ostream &s, const google::LogMessage &m, void *data);private:static std::string m_FilePath;static Hldglog *m_instance;
};#endif

#include "hldglog.h"
#include <iostream>
#include <chrono>
#include <iomanip>
#include <ctime>
#include <functional>using namespace std::chrono_literals;std::string Hldglog::m_FilePath = "./log";
Hldglog *Hldglog::m_instance = nullptr;Hldglog::~Hldglog()
{google::ShutdownGoogleLogging();
}Hldglog *Hldglog::InitGlog(const char *argv, std::string logPath)
{if (m_instance == nullptr){if (logPath.empty()){Hldglog::m_FilePath = "./log";}else{Hldglog::m_FilePath = logPath;}google::InitGoogleLogging(argv); // 初始化谷歌的日志库// 自定义日志格式google::InstallPrefixFormatter(Hldglog::CustomePrefixFormatter, nullptr);FLAGS_log_dir = Hldglog::m_FilePath;       // 设置日志文件存放的目录FLAGS_minloglevel = 0;                     // 设置日志抑制级别FLAGS_stderrthreshold = google::GLOG_INFO; // 设置日志记录到文件的级别FLAGS_alsologtostderr = true;              // 错误信息同时输出到终端和文件FLAGS_colorlogtostderr = true;             // 设置输出到屏幕的日志显示相应颜色FLAGS_max_log_size = 2;                    // 最大日志大小(单位为MB)FLAGS_logbufsecs = 0;                      // 缓冲日志输出,默认为30秒,此处改为立即输出(日志实时输出)FLAGS_stop_logging_if_full_disk = true;    // 当磁盘被写满时,停止日志输出FLAGS_timestamp_in_logfile_name = false;   // 日志文件名取消时间戳// 获取当前日期time_t now = time(nullptr);struct tm *local_time = localtime(&now);// 从tm结构体中获取年、月、日int year = local_time->tm_year + 1900; // tm_year是以1900年为基的int month = local_time->tm_mon + 1;    // tm_mon是以0为1月的int day = local_time->tm_mday;         // tm_mday是月份中的哪一天std::stringstream ss;ss << year << "-" << month << "-" << day;std::string current_date = ss.str();std::string info_log_path = Hldglog::m_FilePath + "/INFO_" + current_date;std::string warn_log_path = Hldglog::m_FilePath + "/WARNING_" + current_date;std::string error_log_path = Hldglog::m_FilePath + "/ERROR_" + current_date;google::SetLogDestination(google::GLOG_INFO, info_log_path.c_str());    // 设置google::GLOG_INFO级别的日志存储路径和文件名前缀google::SetLogDestination(google::GLOG_WARNING, warn_log_path.c_str()); // 设置google::GLOG_WARNING级别的日志存储路径和文件名前缀google::SetLogDestination(google::GLOG_ERROR, error_log_path.c_str());  // 设置google::GLOG_ERROR级别的日志存储路径和文件名前缀google::SetLogFilenameExtension(".log"); // 设置日志文件的扩展名google::EnableLogCleaner(24h * 7);       // 自动删除旧的日志,设置期限为7天m_instance = new Hldglog();}return m_instance;
}void Hldglog::CustomePrefixFormatter(std::ostream &s, const google::LogMessage &m, void *data)
{// [L thread_id] yyyymmdd hh:mm:ss.uuuuuu [file:line]// msg...// google::GetLogSeverityName(m.severity())[0] 获取日志级别s << "[" << google::GetLogSeverityName(m.severity())[0] << ' ' << m.thread_id() << "]"<< ' '<< std::setw(4) << 1900 + m.time().year() << "-"<< std::setw(2) << 1 + m.time().month() << "-"<< std::setw(2) << m.time().day()<< ' '<< std::setw(2) << m.time().hour() << ':'<< std::setw(2) << m.time().min() << ':'<< std::setw(2) << m.time().sec() << "."<< std::setw(6) << m.time().usec()<< ' '<< "[" << m.basename() << ':' << m.line() << "]"<< "\n";
}
  • 使用方法
#include <iostream>
#include "hldglog.h"
#include <unistd.h>using namespace std;int main(int argc, char *argv[])
{Hldglog::InitGlog(argv[0], "./log");HLD_LOG_INFO << "HLD_LOG_INFO";HLD_LOG_WARNING << "HLD_LOG_WARNING";HLD_LOG_ERROR << "HLD_LOG_ERROR";while (true){sleep(10);}return 0;
}
  • 该类设置日志保留的时间为7天

  • 该类的日志输出格式:

    [L thread_id] yyyymmdd hh:mm:ss.uuuuuu [file:line]
    msg…

  • 效果展示

在这里插入图片描述

  • 日志文件的格式
  1. INFO_日期.log
  2. WARNING_日期.log
  3. ERROR_日期.log
std::string info_log_path = Hldglog::m_FilePath + "/INFO_" + current_date;
std::string warn_log_path = Hldglog::m_FilePath + "/WARNING_" + current_date;
std::string error_log_path = Hldglog::m_FilePath + "/ERROR_" + current_date;google::SetLogDestination(google::GLOG_INFO, info_log_path.c_str());    // 设置google::GLOG_INFO级别的日志存储路径和文件名前缀
google::SetLogDestination(google::GLOG_WARNING, warn_log_path.c_str()); // 设置google::GLOG_WARNING级别的日志存储路径和文件名前缀
google::SetLogDestination(google::GLOG_ERROR, error_log_path.c_str());  // 设置google::GLOG_ERROR级别的日志存储路径和文件名前缀

这样设计的好处:确保了当应用程序在同一日内多次启动时,不会生成多个日志文件,从而有效避免了日志分散的问题,保持日志的连续性和管理的便捷性

相关文章:

C++开源库glog使用封装--自定义日志输出格式,设置日志保留时间

glog下载和编译 glog开源地址 https://github.com/google/glog glog静态库编译 cd /home/wangz/3rdParty/hldglog/glogmkdir out mkdir build && cd buildcmake .. -DCMAKE_INSTALL_PREFIX../out -DCMAKE_BUILD_TYPERelease -DBUILD_SHARED_LIBSOFF本文选择的glo…...

linux rc.local不生效

1. 权限问题直接 chmod 755 /etc/rc.d/rc.local 即可 2.本次发现问题 环境复杂造成&#xff0c;系统中有多个版本的JDK&#xff0c;导致tomcat无法启动 systemctl status rc-local.service ● rc-local.service - /etc/rc.d/rc.local CompatibilityLoaded: loaded (/usr/lib…...

ROS2入门21讲__第07讲__节点:机器人的工作细胞

目录 前言 通信模型 案例一&#xff1a;Hello World节点&#xff08;面向过程&#xff09; 运行效果 代码解析 创建节点流程 案例二&#xff1a;Hello World节点&#xff08;面向对象&#xff09; 运行效果 代码解析 创建节点流程 案例三&#xff1a;物体识别节点 …...

k8s node NotReady后会发生什么?

K8s 是一种强大的容器编排和管理平台&#xff0c;能够高效地调度、管理和监控容器化应用程序&#xff1b;其本身使用声明式语义管理着集群内所有资源模型、应用程序、存储、网络等多种资源&#xff0c;Node 本身又属于 K8s 计算资源&#xff0c;上面承载运行着各种类型的应用程…...

uni-starter创建App项目最全流程(日后还有其他功能会不断更新)

一、创建项目 在HbuilderX中点击创建项目&#xff0c;选择uni-starter模板&#xff0c;选择阿里云、Vue3&#xff0c;填写项目名称后点击创建。如果没有下载过uni-starter会自动下载该插件&#xff0c;如下图&#xff1a; 二、 创建云服务器并关联项目 如果是第一次使用&#…...

动态IP和静态IP区别

1.可变性&#xff1a;当设备重新连接时&#xff0c;动态IP将分配新的IP地址&#xff0c;静态IP将保持不变。 2.适用场景&#xff1a;动态IP适用于普通用户或小型办公室&#xff0c;静态IP适用于需要特定IP地址的服务或应用。 3.价格:动态IP通常比静态IP更经济。 4.管理和配置:动…...

蓝牙(2):BR/EDR的连接过程;查询(发现)=》寻呼(连接)=》安全建立=》认证=》pair成功;类比WiFi连接过程。

4.2.1 BR/EDR 流程&#xff1a; 查询&#xff08;发现&#xff09;》寻呼&#xff08;连接&#xff09;》安全建立》认证》pair成功 4.2.1.1 查询&#xff08;发现&#xff09;流程Inquiry (discovering) 类比WiFi的probe request/response 蓝牙设备使用查询流程来发现附近的…...

源码部署EFK

目录 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 单节点 集群(3台节点集群为例) 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kiban…...

CSDN智能总结助手

github项目地址&#xff1a; https://github.com/anjude/little-demo/tree/master 获取CSDN的user name和user token 打开csdn&#xff0c;打开控制台 - Application - Cookies&#xff0c;找到domain为blog.csdn.net的cookie&#xff0c;复制user_name和user_token的值 把上…...

setImmediate是在当前事件循环的所有周期的末尾执行,还是再当前事件循环的当前周期的下一个周期执行?

实际上&#xff0c;setImmediate 的回调函数会在当前事件循环的当前周期的末尾执行&#xff0c;而不是下一个周期。 在事件循环中&#xff0c;任务分为宏任务&#xff08;macrotask&#xff09;和微任务&#xff08;microtask&#xff09;。setImmediate 的回调函数属于宏任务…...

建材行业工程设计资质动态核查不通过怎么办

详细了解核查结果&#xff1a;首先&#xff0c;需要仔细阅读核查结果&#xff0c;了解不通过的具体原因。这些原因可能涉及企业基本情况、技术负责人情况、主要人员情况、设备和厂房情况、业绩和信誉等方面。 针对问题制定整改计划&#xff1a;根据核查结果&#xff0c;针对存…...

二叉数之插入操作

首先是题目 给定二叉搜索树&#xff08;BST&#xff09;的根节点 root 和要插入树中的值 value &#xff0c;将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 &#xff0c;新值和原始二叉搜索树中的任意节点值都不同。 注意&#xff0c;可能存在多种有效…...

【Python】全局变量与init的区别

一个脚本里&#xff0c;设置全局变量&#xff0c;和初始化类时__init__中加载&#xff0c;有什么区别&#xff1f; 在Python脚本中&#xff0c;使用全局变量和在类的__init__方法中加载数据有几个关键区别&#xff1a; 作用域&#xff1a; 全局变量&#xff1a;全局变量在整个…...

JAVA学习-练习试用Java实现“位1的个数”

问题&#xff1a; 编写一个函数&#xff0c;输入是一个无符号整数&#xff08;以二进制串的形式&#xff09;&#xff0c;返回其二进制表达式中数字位数为 1 的个数&#xff08;也被称为汉明重量&#xff09;。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如…...

HTML静态网页成品作业(HTML+CSS)——魅族商城首页网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…...

Windows DNS 服务器配置转发器

DNS服务器转发器 在企业中由于自身条件的限制&#xff0c; 可能本身的DNS新能并不是很好&#xff0c;这个时候通过使用转发器功能&#xff0c; 将收到的DNS请求转发给另外一台高性能的DNS服务器&#xff0c;让其做后面的迭代查询。 1. 选择DNS服务器&#xff0c; 右击选择属性…...

基于FPGA的VGA协议实现----条纹-文字-图片

基于FPGA的VGA协议实现----条纹-文字-图片 引言&#xff1a; ​ 随着数字电子技术的飞速发展&#xff0c;现场可编程门阵列&#xff08;FPGA&#xff09;因其高度的灵活性和并行处理能力&#xff0c;在数字系统设计中扮演着越来越重要的角色。FPGA能够实现复杂的数字逻辑&#…...

hdfs中MapReduce中的shuffle,combine和partitioner(hadoop,Hdfs)

1- MapReduce中shuffle阶段的工作流程以及何如优化该阶段&#xff1f; 分区 &#xff0c;排序 &#xff0c;溢写 &#xff0c;拷贝到对应reduce机器上 &#xff0c;增加combiner &#xff0c;压缩溢写的文件 2-MapReduce中combine的作用&#xff0c;一般使用情景&#xff0c…...

Linux应用入门(二)

1. 输入系统应用编程 1.1 输入系统介绍 常见的输入设备有键盘、鼠标、遥控杆、书写板、触摸屏等。用户经过这些输入设备与Linux系统进行数据交换。这些设备种类繁多&#xff0c;如何去统一它们的接口&#xff0c;Linux为了统一管理这些输入设备实现了一套能兼容所有输入设备的…...

高仿果汁导航模板

参考原文&#xff1a;果汁导航风格模板_1234FCOM专注游戏工具及源码例子分享 极速云...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲&#xff1a; 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年&#xff0c;数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段&#xff0c;基于数字孪生的水厂可视化平台的…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

SpringCloudGateway 自定义局部过滤器

场景&#xff1a; 将所有请求转化为同一路径请求&#xff08;方便穿网配置&#xff09;在请求头内标识原来路径&#xff0c;然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...