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.hqwc.cn/news/139106.html

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

相关文章

2000年至2017年LandScan全球人口分布数据(1KM分辨率)

简介&#xff1a; LandScan全球人口分布数据来自于East View Cartographic&#xff0c;由美国能源部橡树岭国家实验室(ORNL)开发。LandScan运用GIS和遥感等创新方法&#xff0c;是全球人口数据发布的社会标准&#xff0c;是全球最为准确、可靠&#xff0c;基于地理位置的&…

绝对有效,牛津《书虫》全系列完整版( 电子书+MP3 )

&#x1f600;前言 因为像看一下牛津《书虫》系类的&#xff08;PDF和音频&#xff09;找了许久不是链接过期就是要密码要会员太烦了所以在这里整理好打包给大家 在文章末尾 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大…

和硕首次参加展OCP 峰会,将发布多项AI合作项目产品 | 百能云芯

电子代工大厂和硕联合科技宣布&#xff0c;将参与今年的 OCP 全球峰会 (OCP Global Summit)&#xff0c;展示与英伟达 (NVIDIA) 合作成果&#xff0c;包含使用英伟达 GH200 Grace Hopper 超级芯片的 MGX AI 服务器&#xff0c;以及搭载 A100、L40 等服务器产品。 OCP 峰会于 10…

从入门到进阶 之 ElasticSearch 文档、分词器 进阶篇

&#x1f339; 以上分享 ElasticSearch 文档、分词器 进阶篇&#xff0c;如有问题请指教写。&#x1f339;&#x1f339; 如你对技术也感兴趣&#xff0c;欢迎交流。&#x1f339;&#x1f339;&#x1f339; 如有需要&#xff0c;请&#x1f44d;点赞&#x1f496;收藏&#…

JDK 21的新特性总结和分析

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

linux下 u2net tensorrt模型部署

TensorRT系列之 Windows10下yolov8 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov8 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov7 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov6 tensorrt模型加速部署 TensorRT系列之 Linux下 yolov5 tensorrt模型加速…

设计模式截图记录

设计模式截图记录

pdf转二维码怎么做?pdf二维码制作简单技巧

pdf是一种很常见的文件储存格式&#xff0c;一般通知、发票、简历都会保存为这种格式来使用&#xff0c;那么需要将pdf格式文件做成二维码&#xff0c;该用什么方式来制作呢&#xff1f;下面给大家分享一个pdf转二维码的在线工具&#xff0c;可以通过上传文件一键生成二维码&am…

全新自适应导航网模板 导航网系统源码 网址导航系统源码 网址目录网系统源码

帝国CMS7.5开发目录网络程序基本功能描述&#xff1a; 1.一键获取目标站SEO信息。7.5版增加了一键获取会员中心网站信息权重&#xff0c;小程序提交发布&#xff0c;增加了新的自适应模板&#xff1b; 2.访客可以提交&#xff0c;访客提交手动审核&#xff0c;会员提交不审核…

论文研读|TextBack: Watermarking Text Classifiers using Backdooring

目录 论文信息文章简介研究动机研究方法水印生成水印嵌入版权验证 实验结果保真度 & 有效性消融实验 方法评估相关文献 论文信息 论文名称&#xff1a;TextBack: Watermarking Text Classifiers using Backdooring 作者&#xff1a;Nandish Chattopadhyay, et al. Nanyang…

银河麒麟服务器x86安装qemu虚拟机,并安装windows server 2019

安装虚拟机 桌面右键&#xff0c;选择在终端中打开 输入下面的脚本 yum install -y virt-viewer virt-v2v libvirt* qemu* virt-manager 等待安装完成 安装成功 打开虚拟机软件 新建虚拟操作系统&#xff0c;以windows server 2019为例 选择镜像 点击前进 点击&#xff1a;是…

C语言练习题-指针-(编写一个函数,接受一个整型数组和数组的长度作为参数,将数组中的元素按逆序存放)

文章目录 前言题目题目1简单的代码框架 题目2测试用例 题目3测试用例 参考答案题目1答案1解析 答案2解析 题目2答案1答案2 题目3答案1答案2 其他文章 前言 本篇文章的题目为C的基础练习题&#xff0c;指针部分。做这些习题之前&#xff0c;你需要确保已经学习了指针的知识。 本…