当前位置: 首页 > 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专注游戏工具及源码例子分享 极速云...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

前端开发面试题总结-JavaScript篇(一)

文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包&#xff08;Closure&#xff09;&#xff1f;闭包有什么应用场景和潜在问题&#xff1f;2.解释 JavaScript 的作用域链&#xff08;Scope Chain&#xff09; 二、原型与继承3.原型链是什么&#xff1f;如何实现继承&a…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

MySQL用户和授权

开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务&#xff1a; test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...