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

news2024/12/26 11:31:29

glog下载和编译

  • glog开源地址

https://github.com/google/glog

  • glog静态库编译
cd /home/wangz/3rdParty/hldglog/glog

mkdir out 
mkdir build && cd build

cmake ..  -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级别的日志存储路径和文件名前缀

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1685269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何利用Ubuntu服务器运行深度学习项目?

一、整体思路 先配置好服务器端的软件环境&#xff08;工程源码&#xff0c;miniconda&#xff0c;cuda&#xff0c;显卡驱动等&#xff09;&#xff0c;然后用自己电脑的pycharm远程连接服务器运行代码。一句话总结&#xff1a;借用服务器资源运行代码&#xff0c;本地pycharm…

第三节 mybatis-spring-boot-starter 案例分析

tips&#xff1a;可以利用 docker-desktop 快速搭建 MySQL、Redis 等中间件Docker 安装 Redis | 菜鸟教程 上一章&#xff0c;我们完成了一个自定义 Starter &#xff1b; 这一章&#xff0c;我们来看看 Mybatis 是如何使用 Starter&#xff0c;通过学习 mybatis-spring-boot-s…

深度学习模型keras第二十二讲:使用KerasCV进行语义分割

1、语义分割的概念 1.1语义分割的定义 语义分割是一种计算机视觉领域的图像分割技术&#xff0c;其目标是将一张图像中的每个像素分配给预定义的类别。 在图像领域&#xff0c;语义指的是对图像意思的理解。语义分割就是按照“语义”给图像上目标类别中的每一点打上一个标签…

C#屏蔽基类成员

可以用与积累成员名称相同的成员来屏蔽 要让编译器知道你在故意屏蔽继承的成员&#xff0c;可以用new修饰符。否则程序可以成功编译&#xff0c;但是编译器会警告你隐藏了一个继承的成员 using System;class someClass {public string F1 "Someclass F1";public v…

第四节 Starter 加载时机和源码理解

tips&#xff1a;每个 springBoot 的版本不同&#xff0c;代码的实现存会存在不同。 上一章&#xff0c;我们聊到 mybatis-spring-boot-starter&#xff1b; 简单分析了它的结构。 这一章我们将着重分析 Starter 的加载机制&#xff0c;并结合源码进行分析理解。 一、加载实际…

若依解决使用https上传文件返回http路径问题

若依通过HTTPS请求进行文件上传时却返回HTTP的文件链接地址&#xff0c;主要原因是使用了 request.getRequestURL 获取链接地址。 解决办法&#xff1a; 在nginx配置文件location处加上&#xff1a;proxy_set_header X-Forwarded-Scheme $scheme; 然后代码通过request.getHea…

在程序运行中动态改变变量

场景 出于测试目的&#xff0c;需要在程序运行中去改变程序中的参数 思路 动态的去读第三方存储&#xff0c;比如数据库&#xff0c;缓存&#xff0c;甚至是文件 我的实现 这里使用了gflags&#xff0c;通过flaks实现一个api提供flag的修改 Gflags 是 Google 内部使用的命…

人工智能(Educoder)-- 机器学习 -- 神经网络(初级)

第一关 注&#xff1a; 神经网络的起源和应用 起源&#xff1a;神经网络最早由心理学家和神经学家开创&#xff0c;目的是模拟生物神经系统对真实世界物体的交互反应。应用&#xff1a;现代神经网络用于分类&#xff08;如图像识别、文本分类&#xff09;和数值预测&#xff08…

docker启动clickhouse

docker启动clickhouse 创建clickhouse目录拉取镜像启动临时容器, 生成配置文件正式启动 clickhouse越来越流行&#xff0c;本地想安装个测试环境 创建clickhouse目录 后续作为挂载卷使用 mkdir -p /home/gugu/ckdata/data mkdir -p /home/gugu/ckdata/conf mkdir -p /home/gu…

信捷XD系列PLC通讯失败程序无法下载如何设置

如题:最近在使用信捷PLC&#xff0c;有时会出现通讯不上的问题&#xff0c;下面将通讯配置步骤及注意事项分享。 一、确保PLC通电&#xff0c;电脑使用USB通讯线和PLC连接。 二、打开程序&#xff0c;点击串口标识&#xff0c;会弹出通信配置窗口。 三、双击USB通讯这条进行设…

【Python小案例】Python+mysql+PyQt5健康体检报告查询

下载安装Python3.7.8 python官网&#xff1a;https://www.python.org/ PyQt5配置 安装PyQt5 pip install PyQt5pip install qt5_toolspytcharm创建项目 配置外部工具 QTDesigner的Arguments语句不用填 QTDesigner的Working directory语句:$ProjectFileDir$ Pyuic的Argume…

【GDAL】GDAL库学习(C#版本)

1.GDAL 2.VS2022配置GDAL环境&#xff08;C#&#xff09; VS2022工具–NuGet包管理器–管理解决方案的NuGet程序包&#xff0c;直接安装GDAL包。 并且直接用应用到当前的控制台程序中。 找一张tiff格式的图片&#xff0c;或者用格式转换网站&#xff1a;https://www.zamzar.c…

go升级后 编译的exe在win7上无法正常运行

D:/Go/src/runtime/sys_windows_amd64.s:65 x75 fpx22fca sp-0x22fc8日 升级到go 1.21后报一堆错误&#xff0c;要死了啊 原来是go 1.21不支持win7了&#xff0c;必须把go退回到1.20版本 谷歌发布编程语言 Go 1.21 版本&#xff1a;取消支持微软 Win7/8 及苹果 macOS 10.13/10…

爬虫技术升级:如何结合DrissionPage和Auth代理插件实现数据采集

背景/引言 在大数据时代&#xff0c;网络爬虫技术已经成为数据收集的重要手段之一。爬虫技术可以自动化地从互联网上收集数据&#xff0c;节省大量人力和时间成本。然而&#xff0c;当使用需要身份验证的代理服务器时&#xff0c;许多现有的爬虫框架并不直接支持代理认证。这就…

[力扣]——231.2的幂

题目描述&#xff1a; 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 如果存在一个整数 x 使得 n 2x &#xff0c;则认为 n 是 2 的幂次方。 bool isPowerOfTwo(int n){ if(n0)retur…

vue3结合element-plus之如何优雅的使用表格

背景 表格组件的使用在后台管理系统中是非常常见的,但是如果每次使用表格我们都去一次一次地从 element-plus 官网去 复制、粘贴和修改成自己想要的表格。 这样一来也说得过去,但是如果我们静下来细想不难发现,表格的使用都是大同小异的,每次都去复制粘贴,对于有很多表格…

深度学习之基于YOLOV5的口罩检测系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景 随着全球公共卫生事件的频发&#xff0c;口罩成为了人们日常生活中不可或缺的一部分。在公共场所&am…

slam14讲(第8讲、前端里程计)LK光流、直接法

直接法的引出 因为第7讲大部分都是讲特征点法&#xff0c;通过提取orb特征点和点的描述子&#xff0c;来构建两帧图像之间的特征点对应关系。这种方法会有缺点&#xff1a; 关键点和描述子提取计算耗时&#xff0c;如果相机的频率高&#xff0c;则slam算法大部分耗时被占。特…

轻量SEO分析报告程序网站已开心去授权

轻量SEO分析报告程序网站已开心去授权&#xff0c;可以让你生成有洞察力的、 简洁的、易于理解的SEO报告&#xff0c;帮助你的网页排名和表现更好 网站源码免费下载地址抄笔记 (chaobiji.cn)https://chaobiji.cn/

算法学习:快速排序

&#x1f525; 个人主页&#xff1a;空白诗 文章目录 &#x1f680; 引言&#x1f4cc; 快速排序算法核心思想1. 选择基准值&#xff08;Pivot&#xff09;2. 分区操作&#xff08;Partitioning&#xff09;3. 递归排序子序列 &#x1f4cc; JavaScript 实现1. 快速排序主函数2…