• C++项目实战——基于多设计模式下的同步&异步日志系统-⑥-日志等级类与日志消息类设计


    专栏导读

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

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

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

    在这里插入图片描述

    日志等级类设计

    对于日志等级类,我们主要完成两个功能:

    • 定义枚举类
    • 实现转换接口

    日志等级类中使用枚举来设置日志等级,并提供一个将日志等级转化为对应字符串的功能。

    日志等级划分

    日志等级分为以下7个等级:

    • OFF:关闭;
    • DEBUG:调式,调试时的关键信息输出;
    • INFO:提示,普通的提示性日志信息;
    • WARN:警告,不影响运行,但是需要注意的日志;
    • ERROR:错误,程序运行时出现错误的日志;
    • FATAL:致命,一般是代码导致程序无法正常运行的日志;
    • UNKOW:未知,表示未知错误。
    enum class value
    {
        UNKNOW = 0,
        DEBUG,
        INFO,
        WARN,
        ERROR,
        FATAL,
        OFF
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    to_string函数设计

    函数设计思路较为简单,函数参数为value类型,表示日志等级。使用switch语句进行选择输出对应字符串。

    static const char* tostring(LogLevel::value level)
    {
        switch (level)
        {
        case LogLevel::value::DEBUG : return "DEBUG";
        case LogLevel::value::INFO : return "INFO"; 
        case LogLevel::value::WARN : return "WARN"; 
        case LogLevel::value::ERROR : return "ERROR"; 
        case LogLevel::value::FATAL : return "FATAL"; 
        case LogLevel::value::OFF : return "OFF"; 
        default: return "UNKNOW";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    日志等级类整理

    /*
        日志等级类实现:
        1.定义枚举类
        2.转换接口
    */
    
    #ifndef __M_LEVEL_H__
    #define __M_LEVEL_H__
    
    namespace LOG
    {
        class LogLevel
        {
            public:
                enum class value
                {
                    UNKNOW = 0,
                    DEBUG,
                    INFO,
                    WARN,
                    ERROR,
                    FATAL,
                    OFF
                };
    
                static const char* tostring(LogLevel::value level)
                {
                    switch (level)
                    {
                    case LogLevel::value::DEBUG : return "DEBUG";
                    case LogLevel::value::INFO : return "INFO"; 
                    case LogLevel::value::WARN : return "WARN"; 
                    case LogLevel::value::ERROR : return "ERROR"; 
                    case LogLevel::value::FATAL : return "FATAL"; 
                    case LogLevel::value::OFF : return "OFF"; 
                    default: return "UNKNOW";
                    }
                }
        };
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    日志消息类设计

    日志消息类主要是封装一条完整的日志消息所需的内容,其中包括:

    • 时间:描述本条日志输出的时间;
    • 线程ID:描述本条日志是哪一个线程输出的;
    • 日志等级:描述本条日志的等级;
    • 日志文件名:描述本条日志在哪一个源码文件中输出的;
    • 日志行号:描述本条日志在源码文件的哪一行输出的;
    • 日志器名称:描述打印本条日志的日志器名称;
    • 日志数据:本条日志的有效数据载荷。

    日志消息类设计较为简单,如下:

    #ifndef __M_MSG_H__
    #define __M_MSG_H__
    
    /*
        定义日志消息类:
        1.日志的输出时间
        2.日志等级
        3.源文件名称
        4.源代码行号
        5.线程ID
        6.日志主体消息
        7.日志器名称
    */
    
    #include 
    #include 
    #include 
    #include "util.hpp"
    #include "level.hpp"
    
    namespace LOG
    {
        struct LogMsg
        {
            time_t _ctime; // 日志输出时间
            LogLevel::value _level; // 日志等级
            std::string _file; // 源文件名称
            size_t _line; // 源文件行号
            std::thread::id _tid; // 线程ID
            std::string _logger; // 日志器名称
            std::string _payload; // 日志主体消息
    
            LogMsg(LogLevel::value level,
                size_t line,
                const std::string file,
                const std::string logger,
                const std::string msg
            ) : 
            _ctime(util::Date::getTime()),
            _level(level),
            _line(line),
            _tid(std::this_thread::get_id()), // get_id 获取当前线程的ID
            _file(file),
            _logger(logger),
            _payload(msg) {}
        };
    }
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    在这里插入图片描述

  • 相关阅读:
    django/CVE-2017-12794XSS漏洞复现
    单片机的冷启动、热启动、复位
    LeetCode26.删除有序数组中的重复项(双指针法)
    【C++笔试强训】第二十九天
    8路光栅尺磁栅尺编码器或16路高速DI脉冲信号转Modbus TCP网络模块 YL99-RJ45
    SpringCloudAlibaba注册中心与配置中心之利器Nacos实战与源码分析(上)
    TypeScript 之 Promise,Generator和 async
    LeetCode34-34. 在排序数组中查找元素的第一个和最后一个位置
    Flutter气泡框实现
    css3英文文字换行,超过两行...展示
  • 原文地址:https://blog.csdn.net/gllll_yu/article/details/132815137