日志系统——实用类设计,日志等级类设计,日志消息类设计

news2024/7/4 4:27:24

一,实用类设计

该类主要是提前完成一些后面会用到的零碎通用的功能接口,主要有下面几个

1.获取系统时间:这里我们直接用time()函数获取时间返回

2.判断文件是否存在:判断文件我们调用系统接口,stat(),如下所示,第一个为文件路径,第二个是一个结构体,创建传入指针即可,返回0说明存在,-1说明不存在或者错误。

 

 3.获取文件的所在目录路径:以''./abc/a.txt''为例,该文件路径其实就是最后一个'/'以前(包括'/'),这里我们可以直接用string提供的搜索接口即可

 4.创建目录:以"./abc/ad/a.txt"为例,创建目录要一个一个建,先创建/abc,再依次进行,创建目录我们可以调用系统接口mkdir(),如下所示,第一个参数是所建目录路径,第二个参数为该目录权限

代码如下,注意后面三个功能都是关于文件路径的,因此我们将后面三个放到了一个类中实现

#ifndef _M_UTIL_H_
#define _M_UTIL_H_

#include <iostream>
#include <ctime>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace mjw
{
    namespace util
    {
        //设计两个类,时间一个类,后面的文件存在判断,文件目录路径,创建目录分为一个类
        class gettime
        {
            public:
                static size_t nowtime() 
                {
                    return (size_t)time(nullptr);
                }
        };

        class FileDirectory
        {
            public:
            //1.判断文件是否存在
            static bool exist(const std::string& filename)
            {
                struct stat sm;
                return stat(filename.c_str(),&sm)==0;
            }
            //2.获取文件路径
            static std::string getDirectory(const std::string& filename)
            {
                if(filename.empty()) return ".";
                int pos=filename.find_last_of("/\\");
                if(pos==std::string::npos)//pos==npos说明没有找到
                {
                    return ".";
                }

                return filename.substr(0,pos+1);
            }
            //3.创建目录
            static void createDirectory(const std::string& path)
            {
                // ./abc/ab/c.txt
                if(path.empty()) return;
                if(exist(path)) return;
                int pos=0,indox=0;

                while(indox<path.size())
                {
                    pos=path.find_first_of("/\\",indox);
                    //当pos==npos时,说明pos到indox已经没有/,说该创建最后一个文件,创建完break即可
                    if(pos==std::string::npos)
                    {
                        mkdir(path.c_str(),0777);
                        break;
                    }
                    if(!exist(path.substr(0,pos))) mkdir(path.substr(0,pos).c_str(),0777);
                    indox=pos+1;
                }
            }
        };
    }

}
#endif

二,日志等级类设计

 首先我们需要明确划分日志等级的目的,就是在输出时按照等级进行过滤输出,也就是说每一个项目都会设置一个默认的输出等级,只有输出的日志等级大于等于默认输出等级才会输出。

而日志等级类有下面两个功能

1.使用枚举类的方法定义出所有的输出等级

 

 等级如上所示,这里有一个问题为什么OFF可以关闭日志?当我们将默认输出等级设计成OFF时,此时只有等级大于等于OFF的信息可以输出,但是OFF等级是最大的,这样日志的输出就被关闭了。

2.提供一个接口,将对应的枚举等级转换成字符串

DEBUG ->"DEBUG"

模块代码如下

#ifndef _M_LEVEL_H_
#define _M_LEVEL_H_

#include <iostream>

namespace mjwlog
{
    class LogLevel
    {
        public:
        enum class level
        {
            UNKNOW=0, //未知
            DEBUG,    //调试
            INFO,     //提示
            WARN,     //警告
            ERROR,    //错误
            FATAL,    //致命
            OFF       //关闭日志
        };

        static const char* LeveltoString(LogLevel::level l)
        {
            switch(l)
            {
                case LogLevel::level::DEBUG:return "DEBUG";
                case LogLevel::level::INFO:return "INFO";
                case LogLevel::level::WARN:return "WARN";
                case LogLevel::level::ERROR:return "ERROR";
                case LogLevel::level::FATAL:return "FATAL";
                case LogLevel::level::OFF:return "OFF";
            }

            return "UNKNOW";
        }


    };
}
#endif

测试:

 三,日志消息类设计

意义:定义出一条日志存储时所需要的各项要素,同时完成该类构造

日志信息的关键要素
关键要素作用
时间用来过滤日志输出时间
等级过滤日志信息,多等级输出
源文件名称快速定位错误出现的位置
源代码行号快速定位错误出现的位置
线程ID快速定位错误出现的线程
日志器名称支持多日志器共同使用,因此日志器信息也需要过滤
实际日志主题信息主题信息

 代码如下:

 

#ifndef _M_MESSAGE_H_
#define _M_MESSAGE_H_

/* 
    时间	            用来过滤日志输出时间
    等级	            过滤日志信息,多等级输出
    源文件名称	        快速定位错误出现的位置
    源代码行号	        快速定位错误出现的位置
    线程ID	            快速定位错误出现的线程
    日志器名称	        支持多日志器共同使用,因此日志器信息也需要过滤
    实际日志主题信息	 主题信息
*/
#include <iostream>
#include <thread>
#include "level.hpp"
#include "util.hpp"


namespace mjwlog
{
    struct message//struct方便访问类内成员
    {
        size_t _time;   //时间
        size_t _line;   //行号
        LogLevel::level _level; //等级
        std::thread::id _id;    //线程id
        std::string _filename;  //文件名
        std::string _logger;    //日志器名称
        std::string _msg;       //主体信息

        //构造
        message(size_t time=util::gettime::nowtime(),
                size_t line,
                LogLevel::level level,
                std::string filename,
                std::string logger,
                std::string msg)
                :_time(time),
                _line(line),
                _level(level),
                _id(std::this_thread::get_id()),
                _filename(filename),
                _logger(logger),
                _msg(msg)
        {}

    };
}
#endif

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

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

相关文章

Linux命令200例:top是一个基于终端的实时系统监控工具(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

新款2023奥迪A5新车32.24,这款车怎么样?

奥迪公司近期发布了新款A5车型&#xff0c;全国起售价为32.24万元。这款新车凭借其精致的设计和出色的实用性&#xff0c;吸引了大量消费者的关注。本文将结合个人经验和市场调研&#xff0c;对这款新车的特性进行深入剖析。 首先&#xff0c;奥迪A5的外观设计完美融合了实用性…

16.5 【Linux】SELinux 初探

16.5.1 什么是 SELinux SELinux是“ Security Enhanced Linux ”的缩写&#xff0c;字面上的意义就是安全强化的 Linux。 当初设计的目标&#xff1a;避免资源的误用 SELinux 是由美国国家安全局 &#xff08;NSA&#xff09; 开发的&#xff0c;当初开发这玩意儿的目的是因…

Centos7完全卸载已安装的Nginx

查看服务器上安装的nginx版本号&#xff0c;主要是通过ngix的-v或-V选项 Linux下查看Nginx安装目录、版本号信息? -v 显示 nginx 的版本。 -V 显示 nginx 的版本&#xff0c;编译器版本和配置参数。 [rootwww ~]# /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.…

移动硬盘已识别但无法读取怎么办?

移动硬盘已识别但无法读取问题是一个比较常见的问题&#xff0c;通常会以“硬盘无法访问”的提示弹窗形式出现&#xff0c;也曾让很多人苦闷烦恼不已。那么具体的移动硬盘无法读取原因是什么呢&#xff1f; 移动硬盘无法读取的原因 硬盘驱动器可能是没有分区的新驱动器。如果您…

记一次:线程池源码解析

前言&#xff1a;很多时候我们需要使用线程池来处理逻辑&#xff0c;但实际上线程池是如何添加线程&#xff0c;如何执行的呢&#xff1f; 0&#xff1a;创建线程池--略&#xff08;7个参数&#xff09; 1&#xff1a;提交线程池源码 public void execute(Runnable command)…

基于 spring boot 的毕业生信息招聘管理系统【源码在文末】

向上的路&#xff0c;并不拥挤&#xff0c;拥挤是因为大部分人选择了安逸 大学生嘛&#xff0c;论文写不出&#xff0c;代码搞不懂不要紧&#xff0c;重要的是&#xff0c;从这一刻就开始学习&#xff0c;立刻马上&#xff01; 今天带来的是最新的选题&#xff0c;基于 spring…

Python绘图系统5:自定义一个坐标设置控件

文章目录 封装成类数据输入方案设置数据源代码 Python绘图系统&#xff1a;将matplotlib嵌入到tkinter &#x1f4c8;简单的绘图系统 &#x1f4c8;数据导入&#x1f4c8;三维绘图系统 封装成类 xyz这三行其实从代码的角度来说是完全一样的&#xff0c;而且在写这三行组件的时…

Python学习笔记_基础篇(九)_面向对象编程

本篇内容: 1、反射2、面向对象编程3、面向对象三大特性4、类成员5、类成员修饰符6、类的特殊成员7、单例模式 反射 python中的反射功能是由以下四个内置函数提供&#xff1a;hasattr、getattr、setattr、delattr&#xff0c;改四个函数分别用于对对象内部执行&#xff1a;检…

VS2012+AO 10.2.2 项目错误 之内部编译器错误: 步骤“EMIT”

调试时异常消息&#xff1a; 内部编译器错误: 步骤“EMIT” 内部编译器错误: 步骤“COMPILE”的符号 内部编译器错误: 步骤“COMPILE”的符号“<全局命名空间>” 内部编译器错误(0xc0000005 位于地址 00C9FDDC 处): 可能的原因是“CODEGEN”。 好好的项目&…

【逐步剖C++】-第一章-C++入门知识

前言&#xff1a;本文主要介绍有关C入门需掌握的基础知识&#xff0c;包括但不限于以下几个方面&#xff0c;这里是文章导图&#xff1a; 本文较长&#xff0c;内容较多&#xff0c;大家可以根据需求跳转到自己感兴趣的部分&#xff0c;希望能对读者有一些帮助 那么本文也主要以…

springcloud3 hystrix实现服务降级的案例配置2

一 服务降级的说明 1.1 服务降级说明 "服务器忙&#xff0c;请稍后在试"不让客户达等待&#xff0c;立即返回一个友好的提示。 1.2 服务降级的触发情况 1.程序运行异常&#xff1b; 2.超时&#xff1b; 3.服务熔断触发服务降级&#xff1b;4 .线程池/信号量打…

Linux命令200例:ps用于查看当前系统中运行的进程信息(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

【Python】Web学习笔记_flask(5)——会话cookie对象

HTTP是无状态协议&#xff0c;一次请求响应结束后&#xff0c;服务器不会留下对方信息&#xff0c;对于大部分web程序来说&#xff0c;是不方便的&#xff0c;所以有了cookie技术&#xff0c;通过在请求和响应保温中添加cookie数据来保存客户端的状态。 html代码&#xff1a; …

redis Windows版本安装过程(5.0.14)

官网不提供Windows版本的redis安装包&#xff0c;但可以在GitHub网站上找到redis的安装包&#xff1a; Releases tporadowski/redis GitHub &#xff08;相比较Linux其他版本的Redis,Windows版的redis的缺点是版本比较老&#xff0c;官方不提供且不更新&#xff09; 1、zip…

界面组件Telerik UI for WinForms R2 2023——拥有VS2022暗黑主题

Telerik UI for WinForms拥有适用Windows Forms的110多个令人惊叹的UI控件。所有的UI for WinForms控件都具有完整的主题支持&#xff0c;可以轻松地帮助开发人员在桌面和平板电脑应用程序提供一致美观的下一代用户体验。 Telerik UI for WinForms R2 2023于今年6月份发布&…

Vue2到3 Day6 全套学习内容,众多案例上手(内付源码)

简介&#xff1a; Vue2到3 Day1-3 全套学习内容&#xff0c;众多案例上手&#xff08;内付源码&#xff09;_星辰大海1412的博客-CSDN博客本文是一篇入门级的Vue.js介绍文章&#xff0c;旨在帮助读者了解Vue.js框架的基本概念和核心功能。Vue.js是一款流行的JavaScript前端框架…

[C++]笔记 - 知识点积累

一.运算符的优先级 一共15个级别 最高优先级 : () []最低优先级 :逗号表达式倒数第二低优先级 : 赋值和符合赋值(,,-...) ! >算术运算符 > 关系运算符 > && >> || >赋值运算符 二.数据类型转换 隐式类型转换 算数转换 char int long longlong flo…

【2023年11月第四版教材】《第5章-信息系统工程之软件工程(第二部分)》

《第5章-信息系统工程之软件工程&#xff08;第二部分&#xff09;》 1.3 软件设计1.4 软件实现&#xff3b;补充第三版教材内容&#xff3d; 1.5 部署交付 1.3 软件设计 1、结构化设计SD是一种面向数据流的方法&#xff0c;它以SRS和SA阶段所产生的DFD和数据字 典等文档为基础…

如何使用CSS实现一个渐变背景效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现渐变背景效果⭐ 线性渐变&#xff08;Linear Gradient&#xff09;⭐ 径向渐变&#xff08;Radial Gradient&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…