当前位置: 首页 > news >正文

同步异步日志系统-日志落地模块的实现

功能:将格式化完成后的日志消息字符串,输出到指定的位置

扩展:支持同时将日志落地到不同的位置

位置分类:

1.标准输出

2.指定文件(时候进行日志分析)

3.滚动文件(文件按照时间/大小进行滚动切换)

扩展:支持落地方向的扩展

        用户可以自己编写一个新的落地模块,将日志进行其他方向的落地。

 实现思想

1.抽象出一个落地基类

2.之后根据落地方向从基类派生出不同落地方向的子类

3.使用工厂模式进行创建与表示分离

标准输出

class StdoutSink :public LogSink{public:void log(const char* data,size_t len)override{std::cout.write(data,len);}};

输入到指定文件

class FileSink :public LogSink{public://传入文件路径,并且打开文件FileSink(const std::string& pathname):_pathname(pathname){//创建日志文件所在的目录util::File::createDirectory(util::File::path(pathname));//创建并打开日志文件_ofs.open(_pathname,std::ios::binary|std::ios::app);assert(_ofs.is_open());//判断文件是否打开}//将日志消息输入到文件里面void log(const char* data,size_t len)override{_ofs.write(data,len);assert(_ofs.good());}private:std::string _pathname;std::ofstream _ofs;};

以大小进行滚动

class RollBySizeSink :public LogSink{public://传入文件路径,并且打开文件RollBySizeSink(const std::string& basename,size_t max_size):_basename(basename),_max_fsize(max_size),_cur_fsize(0){std::string pathname = createNewFile();//创建日志文件所在的目录util::File::createDirectory(util::File::path(pathname));//创建并打开日志文件_ofs.open(pathname,std::ios::binary|std::ios::app);assert(_ofs.is_open());//判断文件是否打开}//写入前判断文件大小,超过了最大大小就要切换文件void log(const char* data,size_t len)override{if(_cur_fsize>= _max_fsize){std::string pathname = createNewFile();_ofs.close();//关闭原来已经打开的文件。_ofs.open(pathname,std::ios::binary|std::ios::app);assert(_ofs.is_open());_cur_fsize = 0;}_ofs.write(data,len);assert(_ofs.good());_cur_fsize += len;}private:std::string createNewFile(){//获取系统时间,以时间来构造文件扩展名time_t t = util::Date::now();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 <<_name_count++;filename << ".log";return filename.str();}//进行大小判断,超过指定大小就要切换新文件private://基础文件名+扩展文件名(时间生成)组成一个实际的当前输出文件名size_t _name_count=0;std::string _basename;std::ofstream _ofs;size_t _max_fsize;//记录最大大小,当前文件超过了这个大小就要切换文件size_t _cur_fsize;//记录当前文件已经写入的大小};

以时间进行滚动

enum class TimeGap{GAP_SECOND,GAP_MIUTE,GAP_HOUR,GAP_DAY,
};class RollByTimeSink :public bitlog::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_MIUTE:_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 ? bitlog::util::Date::now() : bitlog::util::Date::now() % _gap_size;std::string filename = createNewFile();//创建日志文件所在的目录bitlog::util::File::createDirectory(bitlog::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)override{time_t cur =bitlog::util::Date::now();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 = bitlog::util::Date::now();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 << ".log";return filename.str();}//进行大小判断,超过指定大小就要切换新文件private:std::string _basename;std::ofstream _ofs;size_t _cur_gap;//当前是第几个时间段size_t _gap_size;//时间段的大小};

使用简易工厂模式来创建

class SinkFactory{public:template<typename SinkType,typename ...Args>static LogSink::ptr create(Args &&...args){return std::make_shared<SinkType>(std::forward<Args>(args)...);}};

相关文章:

同步异步日志系统-日志落地模块的实现

功能&#xff1a;将格式化完成后的日志消息字符串&#xff0c;输出到指定的位置 扩展&#xff1a;支持同时将日志落地到不同的位置 位置分类&#xff1a; 1.标准输出 2.指定文件&#xff08;时候进行日志分析&#xff09; 3.滚动文件&#xff08;文件按照时间/大小进行滚动…...

LabVIEW 天然气水合物电声联合探测

天然气水合物被认为是潜在的清洁能源&#xff0c;其储量丰富&#xff0c;预计将在未来能源格局中扮演重要角色。由于其独特的物理化学特性&#xff0c;天然气水合物的探测面临诸多挑战&#xff0c;涉及温度、压力、电学信号、声学信号等多个参数。传统的人工操作方式不仅效率低…...

类型通配符上限

主函数 package typeWildcardTop;import java.util.ArrayList;public class typeWildcardTopTest {/**/public static void main(String[] args) { // test1();test2();}/*测试showList接收ArrayList类型 ArrayList接收各种类型参数创建animals cats mincats集合 传入s…...

嵌入式音视频开发(二)ffmpeg音视频同步

系列文章目录 嵌入式音视频开发&#xff08;零&#xff09;移植ffmpeg及推流测试 嵌入式音视频开发&#xff08;一&#xff09;ffmpeg框架及内核解析 嵌入式音视频开发&#xff08;二&#xff09;ffmpeg音视频同步 嵌入式音视频开发&#xff08;三&#xff09;直播协议及编码器…...

Mongodb数据管理

Mongodb数据管理 1.登录数据库&#xff0c;查看默认的库 [rootdb51~]# mongo> show databases; admin 0.000GB config 0.000GB local 0.000GB> use admin switched to db admin > show tables system.version > admin库&#xff1a;admin 是 MongoDB 的管理…...

Django 创建表 choices的妙用:get_<field_name>_display()

1.定义choices 我在创建表时&#xff0c;对于性别这个字段&#xff0c;定义了choices 选项&#xff0c;1代表男&#xff0c;2代表女 mysql中表的数据如下&#xff0c;里面存储的是1或2 如果我们在网页上展示的时候&#xff0c;想展示“男”或“女”&#xff0c;而不是数字1或2…...

Spring Boot 集成 Kettle

Kettle 简介 Kettle 最初由 Matt Casters 开发&#xff0c;是 Pentaho 数据集成平台的一部分。它提供了一个用户友好的界面和丰富的功能集&#xff0c;使用户能够轻松地设计、执行和监控 ETL 任务。Kettle 通过其强大的功能和灵活性&#xff0c;帮助企业高效地处理大规模数据集…...

自学Java-面向对象高级(final、单例类、枚举类、抽象类、接口)

自学Java-面向对象高级&#xff08;final、单例类、枚举类、抽象类、接口&#xff09; 一、final关键字1、认识final关键字2、final修饰变量的注意3、常量 二、单例类&#xff08;设计模式&#xff09;1、设计模式的概念2、单例设计模式3、单例类有很多形式4、懒汉式单例类5、小…...

Hutool - Cache:简单而强大的缓存实现

目录 1. 缓存简介 2. 引入依赖 3. 常见缓存类型及使用示例 3.1 FIFO 缓存&#xff08;先进先出缓存&#xff09; 3.2 LRU 缓存&#xff08;最近最少使用缓存&#xff09; 3.3 定时缓存 4. 缓存的基本操作 5. 总结 1. 缓存简介 在软件开发中&#xff0c;缓存是一种常用的…...

DeepSeek 通过 API 对接第三方客户端 告别“服务器繁忙”

本文首发于只抄博客&#xff0c;欢迎点击原文链接了解更多内容。 前言 上一期分享了如何在本地部署 DeepSeek R1 模型&#xff0c;但通过命令行运行的本地模型&#xff0c;问答的交互也要使用命令行&#xff0c;体验并不是很好。这期分享几个第三方客户端&#xff0c;涵盖了桌…...

Python 基础-循环

目录 简介 break continue 小结 简介 要计算123&#xff0c;我们可以直接写表达式&#xff1a; >>> 1 2 3 6要计算123...10&#xff0c;勉强也能写出来。 但是&#xff0c;要计算123...10000&#xff0c;直接写表达式就不可能了。 为了让计算机能计算成千上…...

Java和SQL测试、性能监控中常用工具

下面我会详细列举一些在Java和SQL测试、调试、性能监控中常用的工具&#xff0c;并结合项目中提到的各个技术点说明如何选择合适的工具和方法。 一、Java项目常用的测试、调试与性能监控工具 单元测试与集成测试&#xff1a;JUnit/TestNG&#xff1a; 用于编写单元测试和集成测…...

SQL 注入攻击详解[基础篇]:Web 应用程序安全漏洞与防御策略

目录 SQL注入的简介 现代 Web 应用程序中的数据库交互与 SQL 注入攻击 数据库管理系统&#xff08;DBMS&#xff09;架构与 SQL 注入 什么是 SQL 注入&#xff1f; SQL 注入的工作原理 SQL 注入的用例与影响 如何预防 SQL 注入&#xff1f; 数据库分类 数据库类型&am…...

【ArcGIS Pro二次开发】(87):样式_Style的用法

.Stylx类型的文件即为样式库文件&#xff0c;保存了符号样式。 1、根据名字获取当前工程中的style //获取当前工程中的所有style var ProjectStyles Project.Current.GetItems<StyleProjectItem>();//根据名字找出指定的style StyleProjectItem style ProjectStyles.F…...

DEX-EE三指灵巧手:扩展AI与机器人研究的边界

DEX-EE三指灵巧手&#xff0c;由Shadow Robot与Google DeepMind合作开发&#xff0c;以其先进技术和设计&#xff0c;正在引领AI与机器人研究的新趋势。其高精度传感器和灵活的机械手指&#xff0c;能够捕捉复杂的环境数据&#xff0c;为强化学习实验提供了可靠支持。 Shadow R…...

简站主题:简洁、实用、SEO友好、安全性高和后期易于维护的wordpress主题

简站主题以其简洁的设计风格、实用的功能、优化的SEO性能和高安全性而受到广泛好评。 简洁&#xff1a;简站主题采用扁平化设计风格&#xff0c;界面简洁明了&#xff0c;提供多种布局和颜色方案&#xff0c;适合各种类型的网站&#xff0c;如个人博客和企业网站。 实用&…...

23种设计模式 - 责任链

模式定义 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为型设计模式&#xff0c;允许多个对象按链式顺序处理请求&#xff0c;直到其中一个对象处理为止。该模式将请求的发送者和接收者解耦&#xff0c;使多个对象都有机会处理请求。 模式结构…...

Flink SQL与Doris实时数仓Join实战教程(理论+实例保姆级教程)

目录 第一章:Regular Joins 深度解析 1.1 核心原理与适用场景 1.2 电商订单 - 商品实时关联案例 1.2.1 数据流设计 1.2.2 Doris 表设计优化 1.2.3 性能调优要点 第二章:Interval Joins 实战应用 2.1 时间区间关联原理 2.2 优惠券使用有效性验证 2.2.1 业务场景说明 …...

算法——舞蹈链算法

一&#xff0c;基本概念 算法简介 舞蹈链算法&#xff08;Dancing Links&#xff0c;简称 DLX&#xff09;是一种高效解决精确覆盖问题的算法&#xff0c;实际上是一种数据结构&#xff0c;可以用来实现 X算法&#xff0c;以解决精确覆盖问题。由高德纳&#xff08;Donald E.…...

【复现DeepSeek-R1之Open R1实战】系列6:GRPO源码逐行深度解析(上)

目录 4 GRPO源码分析4.1 数据类 GRPOScriptArguments4.2 系统提示字符串 SYSTEM_PROMPT4.3 奖励函数4.3.1 accuracy_reward函数4.3.2 verify函数4.3.3 format_reward函数 4.4 将数据集格式化为对话形式4.5 初始化GRPO Trainer 【复现DeepSeek-R1之Open R1实战】系列3&#xff1…...

Wayback Machine浏览器扩展:你的终极网页存档解决方案

Wayback Machine浏览器扩展&#xff1a;你的终极网页存档解决方案 【免费下载链接】wayback-machine-webextension A web browser extension for Chrome, Firefox, Edge, and Safari 14. 项目地址: https://gitcode.com/gh_mirrors/wa/wayback-machine-webextension Way…...

LongWayToGo

1. 什么是 Apache SeaTunnel&#xff1f; Apache SeaTunnel 是一个非常易于使用、高性能、支持实时流式和离线批处理的海量数据集成平台。它的目标是解决常见的数据集成问题&#xff0c;如数据源多样性、同步场景复杂性以及资源消耗高的问题。 核心特性 丰富的数据源支持&#…...

构建个人开发工具集:从环境配置到工作流自动化实战

1. 项目概述&#xff1a;一个面向开发者的轻量级开源工具最近在整理自己的开发环境时&#xff0c;发现一个挺有意思的小工具&#xff0c;叫gandli/obsd。乍一看这个标题&#xff0c;可能会有点摸不着头脑&#xff0c;它不像那些大名鼎鼎的框架或库&#xff0c;名字直白易懂。但…...

分享一些学习C语言常见的代码

分享一些学习C语言常见的代码 下面是我在学习C语言中用来熟悉写代码的一些程序代码&#xff0c;希望对正在学习C语言的小伙伴有用&#xff01; 1按要求输入输出数据 #include <stdio.h> int main() { int a,b;char c1,c2;float x,y,z;scanf("%5d%5d%c%c%f%f%*f,%f&q…...

丝杆模组优选:台湾高技高精度、模块化、快响应

杆模组作为自动化设备的核心传动部件&#xff0c;其安装方式直接影响负载能力、定位精度及运行稳定性。水平安装依赖丝杆自重平衡&#xff0c;垂直安装需应对重力导致的滑移风险&#xff0c;侧挂安装则需强化抗倾覆结构。不同场景下&#xff0c;丝杆直径、导程、支撑方式及预紧…...

别光跑分了!用UnixBench给你的Linux服务器做一次全面“体检”(附调优实战)

别光跑分了&#xff01;用UnixBench给你的Linux服务器做一次全面“体检”&#xff08;附调优实战&#xff09; 当你拿到一台新配置的Linux服务器&#xff0c;或是发现现有系统出现性能瓶颈时&#xff0c;第一反应是什么&#xff1f;大多数工程师会本能地运行各种基准测试工具&a…...

C语言中常用的几个头文件及库函数

不完全统计&#xff0c;C语言标准库中的头文件有15个之多&#xff0c;所以我主要介绍常用的这四个头文件stdio.h,string.h,math.h,stdlib.h&#xff0c;以后用到其他的再做补充。下面上干货&#xff1a;1.<stdio.h>&#xff1a;定义了输入输出函数、类型以及宏&#xff0…...

python pyproject.toml

聊聊Python的build&#xff0c;这玩意儿其实不算新面孔&#xff0c;早在Python打包工具链里就默默存在了很久&#xff0c;只不过近几年才因为更好的规范性和可扩展性被推到台前。简单说&#xff0c;它是Python官方推荐的打包流程前端工具——不是替代setuptools&#xff0c;而是…...

打卡信奥刷题(3186)用C++实现信奥题 P8052 [ZYOI Round1] Truth/真心话大冒险

P8052 [ZYOI Round1] Truth/真心话大冒险 题目背景 注意&#xff1a;请勿恶意提交代码&#xff0c;浪费评测资源。 一群人参加了聚会&#xff0c;在玩“真心话大冒险”。 题目描述 Charlie 现在盯上了一个人 Percy&#xff0c;Ta 打算找出 Percy 对于 nnn 个异性的好感度的排名…...

P1191 矩形【洛谷算法习题】

P1191 矩形 网页链接 P1191 矩形 题目描述 给出一个 nnn \times nnn 的矩阵&#xff0c;矩阵中&#xff0c;有些格子被染成白色&#xff0c;有些格子被染成黑色&#xff0c;现要求矩阵中白色矩形的数量。 输入格式 第一行&#xff0c;一个整数 nnn&#xff0c;表示矩形的…...