Boost之Log: (3)、简单封装

设计目标:

        1、每个Logging source对应一个目录,可以设置日志文件数,日志大小,目录名,文件名等

        2、所有logging source日志目录都在一个根目录下。

        3、可以动态创建和删除logging source

        4、打印出日期时间和日志严重等级

示例代码:

#include <libs/Core/LogMananger.h>int main(){LogManager::instance().setRootPath("logs");LogManager::instance().addLogger("network", "network", 1024*100, 10);LogManager::instance().addLogger("db", "db", 1024*100, 10);for(int i = 0; i < 10000; i++){LOG(network, info) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, trace) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, warning) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(network, fatal) << "hello world ";LOG(network, debug) << "hello world";LOG(db, info) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, trace) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, warning) << "hello world aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";LOG(db, fatal) << "hello world";LOG(db, debug) << "hello world";}return 0;
}

生成的日志目录结构:

日志格式:

       

LogManager.h

#pragma once
#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/basic_logger.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/core.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/sinks.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/attributes/constant.hpp>
#include <boost/log/exceptions.hpp>
#include <boost/log/keywords/format.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/expressions/formatters/date_time.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>#include <memory>
#include <map>
#include <fstream>
#include <iostream>
#include <string>
#include <mutex>
using namespace std;
namespace sources = boost::log::sources;
namespace sinks = boost::log::sinks;
namespace expressions = boost::log::expressions;
namespace trivial = boost::log::trivial;
namespace keywords = boost::log::keywords;
namespace attributes = boost::log::attributes;class LogManager
{struct LoggerInfo{string m_strName;string m_strPath;int m_nMaxSize;int m_nMaxCount;boost::shared_ptr<sources::severity_logger_mt<trivial::severity_level>> m_pLogger;boost::shared_ptr<sinks::synchronous_sink<sinks::text_file_backend>> m_pSink;};
public:~LogManager();static LogManager& instance();void setRootPath(const string& strRootPath = "");void addLogger(const string& strName, const string& strPath, int nMaxSize, int nMaxCount);void removeLogger(const string& strName);boost::log::sources::severity_logger_mt<trivial::severity_level>& getLogger(const string& strName);
private:LogManager();
private:string m_strRootPath;map<string, LoggerInfo> m_mapLogger;mutex m_oLock;
};#define LOG(name, level) BOOST_LOG_SEV(LogManager::instance().getLogger(#name), boost::log::trivial::severity_level::level)

LogManager.cpp

#include "LogMananger.h"LogManager::LogManager()
{}LogManager::~LogManager()
{}LogManager& LogManager::instance()
{static LogManager t;return t;
}void LogManager::setRootPath(const string& strRootPath)
{m_strRootPath = strRootPath;
}void LogManager::addLogger(const string& strName, const string& strPath, int nMaxSize, int nMaxCount)
{lock_guard<mutex> lk(m_oLock);if(m_mapLogger.contains(strName))return;m_mapLogger[strName] = LoggerInfo();m_mapLogger[strName].m_strName = strName;m_mapLogger[strName].m_strPath = strPath;m_mapLogger[strName].m_nMaxSize = nMaxSize;m_mapLogger[strName].m_nMaxCount = nMaxCount;m_mapLogger[strName].m_pLogger = boost::make_shared<sources::severity_logger_mt<trivial::severity_level>>();m_mapLogger[strName].m_pLogger->add_attribute("LoggerName", attributes::constant<string>(strName));m_mapLogger[strName].m_pLogger->add_attribute("DateTime", attributes::local_clock());boost::shared_ptr<sinks::text_file_backend> pTxtFileBackend = boost::make_shared<sinks::text_file_backend>( keywords::file_name = m_strRootPath + "/" + strPath + "/" + strName + ".log",               //是日志文件大小没达到最大值时,日志写的文件keywords::target_file_name = strName + "_%2N.log",           //当日志文件达到最大值时,日志文件名会被改写,这里的%2N,表示用两位数字表示keywords::rotation_size = nMaxSize,             //单个日志文件最大值,这里是5Mkeywords::open_mode = std::ios_base::out | std::ios_base::app,    //添加模式keywords::time_based_rotation = sinks::file::rotation_at_time_point(12, 0, 0));  //每天12点会重新生成一个日志文件,不管日志文件是否到了最大值m_mapLogger[strName].m_pSink = boost::make_shared<sinks::synchronous_sink<sinks::text_file_backend>>(pTxtFileBackend);m_mapLogger[strName].m_pSink->locked_backend()->set_file_collector(sinks::file::make_collector(keywords::max_files = nMaxCount,                  //最多N个日志文件keywords::max_size = nMaxSize*(1+nMaxCount),         //正目录最大占用多少磁盘空间keywords::target = m_strRootPath + "/" + strPath              //日志保存的目录,前面target_file_name所在的目录));m_mapLogger[strName].m_pSink->locked_backend()->auto_flush(true);m_mapLogger[strName].m_pSink->locked_backend()->scan_for_files();m_mapLogger[strName].m_pSink->set_formatter(expressions::stream<< expressions::if_(expressions::has_attr<boost::posix_time::ptime>("DateTime"))[expressions::stream << "[" << expressions::format_date_time< boost::posix_time::ptime >("DateTime", "%Y-%m-%d %H:%M:%S.%f") << "] "]<< "[" << trivial::severity  <<  "] "<< expressions::smessage);m_mapLogger[strName].m_pSink->set_filter(expressions::has_attr("LoggerName") && expressions::attr<string>("LoggerName") == strName);boost::log::core::get()->add_sink(m_mapLogger[strName].m_pSink);
}void LogManager::removeLogger(const string& strName)
{lock_guard<mutex> lk(m_oLock);if(m_mapLogger.contains(strName))boost::log::core::get()->remove_sink(m_mapLogger[strName].m_pSink);
}sources::severity_logger_mt<trivial::severity_level>& LogManager::getLogger(const string& strName)
{lock_guard<mutex> lk(m_oLock);return *m_mapLogger[strName].m_pLogger;
}

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

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

相关文章

前端试题2#记录

1、介绍以下CSS的盒子模型 盒子模型分为两种&#xff1a; &#xff08;1&#xff09;第一种是W3c标准的盒子模型&#xff08;标准盒模型&#xff09; width和height&#xff1a;内容的宽度、高度&#xff08;不是盒子的宽度、高度&#xff09;。padding&#xff1a;内边距。…

HarmonyOS入门-ArkTS学习(一)

1. 什么是ArkTS语言 学习之前&#xff0c;我们先初步了解下什么是ArkTS 官方指南这样介绍&#xff1a; ArkTS是TS的超集&#xff0c;ArkTS定义了声明式UI描述、自定义组件和动态扩展UI元素的能力&#xff0c;再配合ArkUI开发框架中的系统组件及其相关的事件方法、属性方法等共…

OpenHarmony实战:轻量级系统之子系统移植概述

OpenHarmony系统功能按照“系统 > 子系统 > 部件”逐级展开&#xff0c;支持根据实际需求裁剪某些非必要的部件&#xff0c;本文以部分子系统、部件为例进行介绍。若想使用OpenHarmony系统的能力&#xff0c;需要对相应子系统进行适配。 OpenHarmony芯片适配常见子系统列…

留学生在美国大学利用AI工具到底算不算作弊呢?

自2022年以来&#xff0c;美国大学就开启了一场AI作弊与反作弊大战 战场小至测验&#xff0c;大至申请 这场战争并没有一方胜利&#xff0c;作弊者心思费尽 校方反作弊弄得教授们苦不堪言 那么作为中国留学生该如何避免这场战役呢&#xff1f; 毕竟还是学业要紧呢…… 故事…

让六西格玛培训有效的三个步骤,拿走不谢!

近年来&#xff0c;六西格玛作为一种先进的质量管理方法&#xff0c;被众多企业视为提升产品质量、优化流程、减少浪费的利器。然而&#xff0c;如何使六西格玛培训真正落地生根&#xff0c;发挥出其应有的效果&#xff0c;成为了许多企业关注的焦点。本文&#xff0c;天行健Si…

每日五道java面试题之消息中间件MQ篇(二)

目录&#xff1a; 第一题. RabbitMQ的工作模式第二题. 如何保证RabbitMQ消息的顺序性&#xff1f;第三题. 消息如何分发&#xff1f;第四题. 消息怎么路由&#xff1f;第五题. 如何保证消息不被重复消费&#xff1f;或者说&#xff0c;如何保证消息消费时的幂等性&#xff1f; …

Android adb ime 调试输入法

目录 前言列出所有输入法仅列出输入法 id列出所有输入法的所有信息 启用/禁用 输入法启用输入法禁用输入法 切换输入法还原输入法 前言 安装多个输入法后&#xff0c;可以在设置里进行切换。 既然是开发&#xff0c;能用命令就就命令~ ime 帮助说明&#xff1a; ime <c…

目标检测、识别和语义分割的标注工具安装

计算机视觉 图像分类&#xff08;目标检测&#xff09;&#xff1a;一张图像中是否含某种物体物体定位&#xff08;目标检测与目标识别&#xff09;&#xff1a;确定目标位置和所属类别。语义分割&#xff08;目标分割和目标分类&#xff09;&#xff1a;对图像进行像素级分类…

推荐算法策略需求-rank model优化

1.pred_oobe (base) [rusxx]$ pwd /home/disk2/data/xx/icode/baidu/oxygen/rus-pipeline/pipeline-migrate/UserBaseActiveStatPipeline/his_session (base) [rusxx]$ sh test.sh 2. user_skill_history_dict_expt2包含userid [workxx]$ vim /home/work/xx/du-rus/du_rus_o…

Python 之 Flask 框架学习

毕业那会使用过这个轻量级的框架&#xff0c;最近再来回看一下&#xff0c;依赖相关的就不多说了&#xff0c;直接从例子开始。下面示例中的 html 模板&#xff0c;千万记得要放到 templates 目录下。 快速启动 hello world from flask import Flask, jsonify, url_forapp F…

【edge浏览器无法登录某些网站,以及迅雷插件无法生效的解决办法】

edge浏览器无法登录某些网站&#xff0c;以及迅雷插件无法生效的解决办法 edge浏览器无法登录某些网站&#xff0c;但chrome浏览器可以登录浏览器插件无法使用&#xff0c;比如迅雷如果重装插件重装浏览器重装迅雷后仍然出现问题 edge浏览器无法登录某些网站&#xff0c;但chro…

基于FPGA的SPI_FLASH程序设计

SPI_FLASH简介 spi_flash是一种通用存储器&#xff0c;也称为SPI NOR Flash或SPI Flash。它使用SPI&#xff08;Serial Peripheral Interface&#xff09;接口进行通信&#xff0c;可以通过串行方式读写数据。spi_flash的特点是工作电压低&#xff0c;体积小&#xff0c;读写速…

【单片机家电产品学习记录--红外线】

单片机家电产品学习记录–红外线 红外手势驱动电路&#xff0c;&#xff08;手势控制的LED灯&#xff09; 原理 通过红外线对管&#xff0c;IC搭建的电路&#xff0c;实现灯模式转换。 手势控制灯模式转换&#xff0c;详细说明 转载 1《三色调光LED台灯电路》&#xff0c…

矩阵空间秩1矩阵小世界图

文章目录 1. 矩阵空间2. 微分方程3. 秩为1的矩阵4. 图 1. 矩阵空间 我们以3X3的矩阵空间 M 为例来说明相关情况。目前矩阵空间M中只关心两类计算&#xff0c;矩阵加法和矩阵数乘。 对称矩阵-子空间-有6个3X3的对称矩阵&#xff0c;所以为6维矩阵空间上三角矩阵-子空间-有6个3…

【Turtle】海龟先生

什么是编程 计算机只懂0和1这样的语言&#xff0c;可是我们不懂&#xff0c;当我们希望 计算要能帮我们做事情的时候&#xff0c;该怎么办呢&#xff1f; 我们需要一种更简便的方法告诉计算机要做什么&#xff0c;所以人类发明了编程语言 利用计算机编程语言&#xff0c;我们…

硬件了解 笔记

motherboard的高低端区别在哪里&#xff1f; 核心&#xff1a;从单核变成双核&#xff0c;多核&#xff08;几核就是几个打工人&#xff09; 多线程&#xff1a;6核本来对应6个线程&#xff0c;但是多线程就是说6核对应12个线程 频率 主频&#xff1a;平时打工的速度 睿频&…

iNeuOS工业互联网操作系统,“低代码”表单开发应用过程(一)

iNeuOS工业互联网操作系统&#xff0c;“低代码”表单开发应用过程&#xff08;一&#xff09; 目 录 1. 概述... 2 2. “低代码”表单开发应用过程... 2 1. 概述 iNeuOS工业互联网操作系统“表单设计”功能经过升级后&#xff0c;能够适用于更多应用场景&…

Altair® FluxMotor® 电机拓扑探索和多物理场优化

Altair FluxMotor 电机拓扑探索和多物理场优化 FluxMotor 致力于解决电机的整体设计问题。该软件工具可帮助工程师加快电机设计速度&#xff0c;在考虑多物理场约束条件的同时快速探究各种参数配置&#xff0c;并在几分钟内选出完善的可能。 FluxMotor 具有简单直观的使用界面…

美摄科技AI智能图像矫正解决方案

图像已经成为了企业传播信息、展示产品的重要媒介&#xff0c;在日常拍摄过程中&#xff0c;由于摄影技巧的限制和拍摄环境的复杂多变&#xff0c;许多企业面临着图像内容倾斜、构图效果不佳等挑战&#xff0c;这无疑给企业的形象展示和信息传递带来了不小的困扰。 美摄科技深…

索引下推(Index Condition Pushdown,简称 ICP)

Mysql可以分为Server层和存储引擎层 所以&#xff0c;最终进行I/O的是存储引擎对文件系统进行I/O操作 索引下推&#xff08;Index Condition Pushdown&#xff0c;简称 ICP&#xff09; 对应InnoDB&#xff0c;索引下推适用于非聚簇索引&#xff08;二级索引&#xff09;。 …