C++项目实战——基于多设计模式下的同步异步日志系统-⑫-日志宏全局接口设计(代理模式)

文章目录

  • 专栏导读
  • 日志宏&全局接口设计
  • 全局接口测试
  • 项目目录结构整理
  • 示例代码
    • 拓展示例代码

专栏导读

🌸作者简介:花想云 ,在读本科生一枚,C/C++领域新星创作者,新星计划导师,阿里云专家博主,CSDN内容合伙人…致力于 C/C++、Linux 学习。

🌸专栏简介:本文收录于 C++项目——基于多设计模式下的同步与异步日志系统

🌸相关专栏推荐:C语言初阶系列C语言进阶系列C++系列数据结构与算法Linux

在这里插入图片描述

日志宏&全局接口设计

本章我们将完成提供全局接口&宏函数,对日志系统接口进行使用便捷性优化(避免用户自己创建单例)。

设计思想:

  • 提供获取指定日志器的全局接口(避免用户自己操作单例对象);
  • 使用宏函数对日志器的接口进行代理(代理模式);
  • 提供宏函数,直接通过默认日志器进行日志的标准输出打印(省去获取日志器的操作);
#ifndef __MY_LOG__
#define __MY_LOG__
#include "logger.hpp"namespace LOG
{// 1.提供获取指定日志器的全局接口(避免用户自己操作单例对象)Logger::ptr getLogger(const std::string &name){return LOG::LoggerManager::getInstance().getLogger(name);}Logger::ptr rootLogger(){return LOG::LoggerManager::getInstance().rootLogger();}// 2.实用宏函数对日志器的接口进行代理(代理模式)#define debug(fmt, ...) debug(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define info(fmt, ...) info(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define warn(fmt, ...) warn(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define error(fmt, ...) error(__FILE__, __LINE__, fmt, ##__VA_ARGS__)#define fatal(fmt, ...) fatal(__FILE__, __LINE__, fmt, ##__VA_ARGS__)// 3.提供宏函数,直接通过默认日志器进行日志的标准输出打印#define DEBUG(fmt, ...) LOG::rootLogger()->debug(fmt, ##__VA_ARGS__)#define INFO(fmt, ...) LOG::rootLogger()->info(fmt, ##__VA_ARGS__)#define WARN(fmt, ...) LOG::rootLogger()->warn(fmt, ##__VA_ARGS__)#define ERROR(fmt, ...) LOG::rootLogger()->error(fmt, ##__VA_ARGS__)#define FATAL(fmt, ...) LOG::rootLogger()->fatal(fmt, ##__VA_ARGS__)}
#endif

全局接口测试

测试代码

void log_test()
{DEBUG("%s", "测试日志");INFO("%s", "测试日志");WARN("%s", "测试日志");ERROR("%s", "测试日志");FATAL("%s", "测试日志");size_t count = 0;while(count < 300000){FATAL("测试日志-%d", count++);}
}
int main()
{log_test();return 0;
}

项目目录结构整理

在这里插入图片描述

示例代码

// example/test.cc
#include "../logs/log.h"
#include <unistd.h>void log_test(const std::string& name)
{INFO("%s", "测试开始");LOG::Logger::ptr logger = LOG::LoggerManager::getInstance().getLogger("async_logger");logger->debug(__FILE__, __LINE__, "%s", "测试日志");logger->info(__FILE__, __LINE__, "%s", "测试日志");logger->warn(__FILE__, __LINE__, "%s", "测试日志");logger->error(__FILE__, __LINE__, "%s", "测试日志");logger->fatal(__FILE__, __LINE__, "%s", "测试日志");INFO("%s", "测试完毕");
}
int main()
{std::unique_ptr<LOG::LoggerBuilder> builder(new LOG::GlobalLoggerBuilder());builder->buildLoggerName("async_logger");builder->buildLoggerLevel(LOG::LogLevel::value::WARN);builder->buildFormatter("[%c][%f:%l]%m%n");builder->buildLoggerType(LOG::LoggerType::LOGGER_ASYNC);builder->buildSink<LOG::FileSink>("./logfile/async.log");builder->buildSink<LOG::StdOutSink>();builder->buildSink<LOG::RollBySizeSink>("./logfile/roll-async-by-size", 1024 * 1024);builder->build();log_test("async_logger");return 0;
}

拓展示例代码

// extent/test.cc
#include "../logs/log.h"
#include <unistd.h>enum class TimeGap
{GAP_SECOND,GAP_MINUTE,GAP_HOUR,GAP_DAY
};
class RollByTimeSink : public LOG::LogSink
{
public:// 构造时传入文件名,并打开文件,将操作句柄管理起来RollByTimeSink(const std::string &basename, TimeGap gap_type) : _basename(basename){switch(gap_type){case TimeGap::GAP_SECOND: _gap_size = 1; break;case TimeGap::GAP_MINUTE: _gap_size = 60; break;case TimeGap::GAP_HOUR: _gap_size = 3600; break;case TimeGap::GAP_DAY: _gap_size = 3600 * 24; break;}_cur_gap = _gap_size == 1? LOG::util::Date::getTime() : LOG::util::Date::getTime() % _gap_size; // 获取当前是第几个时间段std::string filename = createNewFile();LOG::util::File::createDirectory(LOG::util::File::path(filename));_ofs.open(filename, std::ios::binary | std::ios::app);assert(_ofs.is_open());}// 将日志消息写入到标准输出,判断当前时间是否是当前文件的时间段,不是则切换文件void log(const char* data, size_t len){time_t cur = LOG::util::Date::getTime();if((cur % _gap_size) != _cur_gap){_ofs.close();std::string filename = createNewFile();_ofs.open(filename, std::ios::binary | std::ios::app);assert(_ofs.is_open());}_ofs.write(data, len);assert(_ofs.good());}
private:std::string createNewFile(){time_t t = LOG::util::Date::getTime();struct tm lt;localtime_r(&t, &lt);std::stringstream filename;filename << _basename;filename << lt.tm_year + 1900;filename << lt.tm_mon + 1;filename << lt.tm_mday;filename << lt.tm_hour;filename << lt.tm_min;filename << lt.tm_sec;filename << "-";filename << ".log";return filename.str();}
private:std::string _basename;size_t _gap_size; // 时间段的大小int _cur_gap; // 当前是第几个时间段std::ofstream _ofs;
};int main()
{std::unique_ptr<LOG::LoggerBuilder> builder(new LOG::GlobalLoggerBuilder());builder->buildLoggerName("async_logger");builder->buildLoggerLevel(LOG::LogLevel::value::WARN);builder->buildFormatter("[%c][%f:%l]%m%n");builder->buildLoggerType(LOG::LoggerType::LOGGER_ASYNC);builder->buildSink<LOG::FileSink>("./logfile/async.log");builder->buildSink<LOG::StdOutSink>();builder->buildSink<RollByTimeSink>("./logfile/roll-async-by-time", TimeGap::GAP_SECOND);LOG::Logger::ptr logger = builder->build();size_t cur = LOG::util::Date::getTime();while(LOG::util::Date::getTime() < cur + 5){logger->fatal("这是一条测试日志");}return 0;
}

在这里插入图片描述

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

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

相关文章

【前端学习】—bind、call、apply(四)

【前端学习】—bind、call、apply(四) 一、代码题 <script>var name="freeman";function sayAuthor(){var name=

PCLVisualizer显示点云的深层用法

以下代码均是在QT中使用QVTKOpenGLNativeWidget的简单教程以及案例-CSDN博客文章的基础上&#xff0c;修改按钮对应的槽函数中的程序。 1.显示文件中点云颜色属性信息&#xff0c;利用PointCloudColorHandlerRGBField得到每个点云对应的颜色。 pcl::PointCloud<pcl::PointX…

Vuex中多个参数显示undefined的解决方案

笔者今天在使用Vuex中的mutations改变state里面的全局状态的值&#xff0c;获取到的数据却怎么都是第一个参数是可以获取到,但是第二个就获取不到&#xff0c;就显示undefined 问题代码 mutations: {multiparameter(state,id,newStatus) {console.log("数据的Key&#x…

【前端】Js

目 录 一.前置知识第一个程序JavaScript 的书写形式注释输入输出 二.语法概览变量的使用理解 动态类型基本数据类型 三.运算符算术运算符赋值运算符 & 复合赋值运算符自增自减运算符比较运算符逻辑运算符位运算移位运算 四.条件语句if 语句三元表达式switch 五.循环语句whi…

ORA-12541:TNS:no listener 无监听程序

问题截图 解决方法 1、删除Listener 新建一个新的 2、主机为服务器ip 3、设置数据库环境 只需要设置实例名不需要设置路径 4、服务命名 一样设置为ip 服务名与监听名一直 eg&#xff1a;orcl

Variations-of-SFANet-for-Crowd-Counting记录

论文&#xff1a;Encoder-Decoder Based Convolutional Neural Networks with Multi-Scale-Aware Modules for Crowd Counting 论文链接&#xff1a;https://arxiv.org/abs/2003.05586 源码链接&#xff1a;GitHub - Pongpisit-Thanasutives/Variations-of-SFANet-for-Crowd-C…

云原生场景下高可用架构的最佳实践

作者&#xff1a;刘佳旭&#xff08;花名&#xff1a;佳旭&#xff09;&#xff0c;阿里云容器服务技术专家 引言 随着云原生技术的快速发展以及在企业 IT 领域的深入应用&#xff0c;云原生场景下的高可用架构&#xff0c;对于企业服务的可用性、稳定性、安全性越发重要。通…

GFS分布式文件系统实验

GFS概念 Gluster 是一个开源的分布式文件系统 它是一个C/S架构 由存储服务器、客户端以及NFS/Samba存储网关组成 没有元数据服务器组件&#xff0c;这有助于提升整个系统的性能&#xff0c;可靠性和稳定性 文件系统定义 负责实现数据存储方式&#xff0c;以什么格式保存在…

Spring5应用之高级注解开发

作者简介&#xff1a;☕️大家好&#xff0c;我是Aomsir&#xff0c;一个爱折腾的开发者&#xff01; 个人主页&#xff1a;Aomsir_Spring5应用专栏,Netty应用专栏,RPC应用专栏-CSDN博客 当前专栏&#xff1a;Spring5应用专栏_Aomsir的博客-CSDN博客 文章目录 参考文献前言Conf…

CentOS 7 部署Jellyfin详细教程

前言 Jellyfin是免费、开源的媒体服务器解决方案&#xff0c;它能让我们轻松地管理和访问个人媒体文件&#xff0c;如电影、音乐等。本文将向您介绍如何快速搭建和部署Jellyfin&#xff0c;并分享一些最佳实践和技巧&#xff0c;帮助您更好地利用这个强大的媒体服务器解决方案。…

2.MySQL表的操作

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 表的操作 (1)表的创建 CREATE TABLE table_name ( field1 datatype, field2 datatype, field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎; 存储引擎的不同会导致创建表的文件不同。 换个引擎。 t…

xcode打包macos报错:FlutterInputs.xcfilelist 和 FlutterOutputs.xcfilelist

xcode 打包macos的时候&#xff0c;报错如下&#xff1a; Unable to load contents of the file list: ‘macos/ephemeral/FlutterInputs.xcfilelist’ ‘macos/ephemeral/FlutterOutputs.xcfilelist’ 解决方案&#xff1a; 我的项目macos下没有找到FlutterInputs.xcfilelis…

angular项目指定端口,实现局域网内ip访问

直接修改package.json文件 "dev": "ng serve --host 0.0.0.0 --port 8080"终端运行npm run dev启动项目。 这里就指定了使用8080端口运行项目&#xff0c;同时局域网内的其他电脑可以通过访问运行项目主机的ip来访问项目 例如项目运行在ip地址为192.168.2…

jmeter压测

jmeter强大到很强大 hh~也要压测go的一些东西&#xff0c;这是三年前做的东西了&#xff0c;jmeter不支持grpc调用所以写了一个spring小服务中间层&#xff1a; 具体的jmeter开始了 这里设置线程相关 <h3>调用哪个服务的哪个方法</h3> <h3>BeanShell PrePro…

喜报 | 擎创科技实力亮相2023科创会并荣获科技创新奖

近日&#xff0c;由国家互联网数据中心产业技术创新战略联盟&#xff08;NIISA&#xff09;主办的“2023第二届国际互联网产业科技创新大会暨互联网创新产品展览会”于北京圆满落幕。 擎创科技副总裁冯陈湧受邀出席本次论坛&#xff0c;并发表了“银行分布式核心智能运维体系思…

Unity3D 基础——使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果

使用 Mathf.SmoothDamp 函数制作相机的缓冲跟踪效果&#xff0c;让物体的移动不是那么僵硬&#xff0c;而是做减速的缓冲效果。将以下的脚本绑定在相机上&#xff0c;然后设定好 target 目标对象&#xff0c;即可看到相机的缓动效果。通过设定 smoothTime 的值&#xff0c;可以…

洗地机什么牌子好用?洗地机排名

洗地机是如今清洁工作中非常重要的设备&#xff0c;它可以提高清洁效率&#xff0c;保持地面卫生&#xff0c;并减轻人力劳动的负担&#xff0c;市面上有许多不同品牌的洗地机&#xff0c;那么洗地机哪个牌子最好用呢?下面我们来介绍一下洗地机排名&#xff0c;并分析其热门型…

DIY私人图床:使用CFimagehost源码自建无需数据库支持的PHP图片托管服务

文章目录 1.前言2. CFImagehost网站搭建2.1 CFImagehost下载和安装2.2 CFImagehost网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

点云处理【三】(点云降采样)

点云降采样 第一章 点云数据采集 第二章 点云滤波 第二章 点云降采样 1. 为什么要降采样&#xff1f; 我们获得的数据量大&#xff0c;特别是几十万个以上的点云&#xff0c;里面有很多冗余数据&#xff0c;会导致处理起来比较耗时。 降采样是一种有效的减少数据、缩减计算量…