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,             //单个日志文件最大值,这里是5M
            keywords::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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从python角度解析selenium原理

1、selenium工作流程 2、selenium工作原理 &#xff08;1&#xff09;客户端和服务端之间实际是通过http协议进行通信&#xff0c;服务端的接口文档可参考&#xff1a;https://github.com/SeleniumHQ/selenium/wiki/JsonWireProtocol#sessionsessionidelement &#xff08;2&…

softmax函数的功能及用法

Softmax函数是一种常用的激活函数&#xff0c;通常用于多分类问题的输出层。其功能是将一个具有任意实数值的向量&#xff08;通常称为“logits”&#xff09;转换为一个概率分布&#xff0c;其中每个元素的值表示对应类别的概率。 Softmax函数的公式如下&#xff1a; 给定一…

windows下通过vscode访问ubuntu(绝大部分Linux下开发所采用的方案)

前言 本篇博客是介绍VSCode远程连接Ubuntu进行开发的解决方案&#xff0c;前提是安装好了VMWare&#xff0c;Ubuntu&#xff0c;windows下的VSCode。 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关…

库存超卖问题分析

3.5 库存超卖问题分析 有关超卖问题分析&#xff1a;在我们原有代码中是这么写的 if (voucher.getStock() < 1) {// 库存不足return Result.fail("库存不足&#xff01;");}//5&#xff0c;扣减库存boolean success seckillVoucherService.update().setSql(&quo…

Nginx 高级

文章目录 Nginx反向代理概念配置 负载均衡概念配置 动静分离概念配置 网关防盗链keepalivednginx跨域 Nginx 反向代理 概念 反向代理&#xff08;Reverse Proxy&#xff09;方式是指以代理服务器来接受internet上的连接请求&#xff0c;然后将请求转发给内部网络上的服务器&…

深入理解数据结构第二弹——二叉树(2)——堆排序及其时间复杂度

看这篇前请先把我上一篇了解一下&#xff1a;深入理解数据结构第一弹——二叉树&#xff08;1&#xff09;——堆-CSDN博客 前言&#xff1a; 相信很多学习数据结构的人&#xff0c;都会遇到一种情况&#xff0c;就是明明最一开始学习就学习了时间复杂度&#xff0c;但是在后期…

电商-广告投放效果分析(KMeans聚类、数据分析-pyhton数据分析

电商-广告投放效果分析&#xff08;KMeans聚类、数据分析&#xff09; 文章目录 电商-广告投放效果分析&#xff08;KMeans聚类、数据分析&#xff09;项目介绍数据数据维度概况数据13个维度介绍 导入库&#xff0c;加载数据数据审查相关性分析数据处理建立模型聚类结果特征分析…

Ceph学习 - 1.存储知识

文章目录 1.存储基础1.1 基础知识1.1.1 存储基础1.1.2 存储使用 1.2 文件系统1.2.1 简介1.2.2 数据存储1.2.3 存储应用的基本方式1.2.4 文件存储 1.3 小结 1.存储基础 学习目标&#xff1a;这一节&#xff0c;我们从基础知识、文件系统、小节三个方面来学习。 1.1 基础知识 1.…

day01 51单片机

51单片机学习 1 51单片机概述 1.1 51单片机简介 目前使用的51单片机一般是宏晶STC89系列,这其中流传最广的版本,也是我们课程的主角,就是STC89C52RC。 1.2 命名规则 1.3 单片机最小应用系统 2 点亮LED灯 2.1 硬件原理图 这个原理图非常简单,VCC接保护电阻R1,串联LED1最…

IOTX:未来市场爆发点的RWA协议?DePIN赛道被低估的龙头

从基本面来看&#xff0c;IoTeX的目标是创建一个连接的世界&#xff0c;在这个世界中&#xff0c;每个人都能控制自己的数据、设备和身份。通过区块链技术&#xff0c;IoTeX旨在解锁智能设备和数据的潜力&#xff0c;支持新一代的现实世界Dapp和数字资产的发展。IOTX始终致力于…

个性化内容的力量:Kompas.ai如何帮你定制内容

在当今的数字化营销环境中&#xff0c;个性化内容已经成为品牌与消费者建立深层次联系的关键。个性化内容不仅能够更好地满足用户的需求&#xff0c;还能够加深用户的品牌体验&#xff0c;从而提高用户满意度和忠诚度。本文将深入探讨个性化内容在提升用户参与度和忠诚度方面的…

Incus:新一代容器与虚拟机编排管理引擎

Incus是什么&#xff1f; Incus是一个用于编排管理应用型容器、系统型容器及虚拟机实例的管理工具。它是对 Canonical LXD 的继承与发展&#xff0c;引入了更多的存储驱动支持。 Incus项目的产品地址&#xff1a;Linux Containers - Incus - Introduction 在 LXC-Incus 项目…

Java练习

这个练习我用到了继承&#xff0c;多态和封装。 1.继承&#xff1a; Animal 类是一个抽象类&#xff0c;它有两个子类 Dog 和 Cat。 Dog 和 Cat 分别继承自 Animal 类&#xff0c;因此它们可以使用 Animal 类中定义的属性和方法&#xff0c;同时也可以有自己特有的属性和方法。…

鸿蒙OS元服务开发:【(Stage模型)学习窗口沉浸式能力】

一、体验窗口沉浸式能力说明 在看视频、玩游戏等场景下&#xff0c;用户往往希望隐藏状态栏、导航栏等不必要的系统窗口&#xff0c;从而获得更佳的沉浸式体验。此时可以借助窗口沉浸式能力&#xff08;窗口沉浸式能力都是针对应用主窗口而言的&#xff09;&#xff0c;达到预…

基于springboot+vue+Mysql的教学视频点播系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

pymc,一个灵活的的 Python 概率编程库!

目录 前言 安装与配置 概率模型 贝叶斯推断 概率分布 蒙特卡罗采样 贝叶斯网络 实例分析 PyMC库的应用场景 1. 概率建模 2. 时间序列分析 3. 模式识别 总结 前言 大家好&#xff0c;今天为大家分享一个超强的 Python 库 - pymc Github地址&#xff1a;https://gith…

黄金票据攻击

黄金票据攻击——域内横向移动技术 一、黄金票据攻击介绍&#xff1a; 黄金票据攻击是一种滥用Kerberos身份认证协议的攻击方式&#xff0c;它允许攻击者伪造域控krbtgt用户的TGT&#xff08;Ticket-Granting Ticket&#xff09;。通过这种方法&#xff0c;攻击者可以生成有效…

怎么禁止特定程序运行

计算机已经成为了人们日常生活和工作中不可或缺的工具。 然而&#xff0c;随着计算机应用的广泛化&#xff0c;如何管理和控制计算机上的程序运行也成为了一个亟待解决的问题。 特别是在企业、学校或一些需要严格控制计算机使用环境的场所。 为什么要禁止特定程序运行&#x…

Catcatcat【杂项 攻防世界】

知识点&#xff1a; strings 命令 打印文件中可以打印的字符&#xff0c;可以是任意文件grep flag 过滤出文件中的flag关键字rabbit加密 深入了解Rabbit加密技术&#xff1a;原理、实现与应用-CSDN博客对称加密算法需要密钥&#xff0c;也可不设置数据开头固定&#xff1a;U2F…

6.8物联网RK3399项目开发实录-驱动开发之RTC实时时钟的使用(wulianjishu666)

90款行业常用传感器单片机程序及资料【stm32,stc89c52,arduino适用】 链接&#xff1a;https://pan.baidu.com/s/1M3u8lcznKuXfN8NRoLYtTA?pwdc53f RTC 使用 简介 AIO-3399J 开发板上有 一个集成于 RK808 上的RTC(Real Time Clock)&#xff0c;主要功能有时钟&#xff0c…