muduo网络库剖析——日志Log类

muduo网络库剖析——日志Log类

  • 前情
    • 从muduo到my_muduo
  • 概要
    • 日志
    • 日志级别
  • 框架与细节
    • 成员
    • 函数
  • 源码

前情

从muduo到my_muduo

作为一个宏大的、功能健全的muduo库,考虑的肯定是众多情况是否可以高效满足;而作为学习者,我们需要抽取其中的精华进行简要实现,这要求我们足够了解muduo库。

做项目 = 模仿 + 修改,不要担心自己学了也不会写怎么办,重要的是积累,学到了这些方法,如果下次在遇到通用需求的时候你能够回想起之前的解决方法就够了。送上一段话!

在这里插入图片描述

概要

日志

日志是用来记录重大事件的工具。
日志文件是重要的系统信息文件,其中记录了很多重要的系统事件。包括用户的登录信息,系统的启动信息,系统的安全信息,邮件相关信息,各种服务相关信息。
日志对于安全来说也很重要,它记录了每天系统发生的各种事情,通过日志来检查错误发生的原因,或者受到攻击时攻击者留下的痕迹。

日志级别

在这里插入图片描述
上面是muduo库的主要日志级别。
在这里插入图片描述
上面是我搜索到的日志级别解释。

框架与细节

成员

  1. 日志级别划分

    我们这里主要用到INFO、DEBUG、WARN、ERROR、FATAL作为我们小规模的日志库日志级别划分。

函数

  1. 日志级别设置

    在这里插入图片描述

    static修饰类成员函数则该成员函数属于整个类,而非类对象,调用需要加类域,初始化要在类外。

  2. 日志实例创建——单例模式

    我们通过返回静态变量能够获得唯一的日志实例,使用的是懒汉式单例模式。有关单例模式,想要了解复习的uu可以跳转到此。

  3. 写日志

    • 关于写日志,我们需要确定统一的写的格式,muduo库选择使用宏定义的方式来统一我们写单条日志的格式。
      在这里插入图片描述 这里使用到了是将宏定义做成流对象进行传输,类似于c++中的cout。我们同样可以使用类似于printf的格式类型来实现我们的日志输出格式化。比如:

       #define LOG_INFO(logmsgformat, ...)                             \
           do {                                                        \
               Log& lp = Log::getInstance();                           \
               lp.setLogLevel(INFO);                                   \
               char buf[64] = {0};                                     \
               snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
               lp.writeLog(buf);                                       \
           } while (0)
       
       #define LOG_DEBUG(logmsgformat, ...)                            \
           do {                                                        \
               Log& lp = Log::getInstance();                           \
               lp.setLogLevel(DEBUG);                                  \
               char buf[64] = {0};                                     \
               snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
               lp.writeLog(buf);                                       \
           } while (0)
       
       #define LOG_WARN(logmsgformat, ...)                             \
           do {                                                        \
               Log& lp = Log::getInstance();                           \
               lp.setLogLevel(WARN);                                   \
               char buf[64] = {0};                                     \
               snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
               lp.writeLog(buf);                                       \
           } while (0)
       
       #define LOG_ERROR(logmsgformat, ...)                            \
           do {                                                        \
               Log& lp = Log::getInstance();                           \
               lp.setLogLevel(ERROR);                                  \
               char buf[64] = {0};                                     \
               snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
               lp.writeLog(buf);                                       \
           } while (0)
       
       #define LOG_FATAL(logmsgformat, ...)                            \
           do {                                                        \
               Log& lp = Log::getInstance();                           \
               lp.setLogLevel(FATAL);                                  \
               char buf[64] = {0};                                     \
               snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
               lp.writeLog(buf);                                       \
               exit(-1);                                               \
           } while (0)
      
    • VA_ARGS 是一个预处理宏,用于可变参数宏中。当你在一个宏定义中使用可变参数时,VA_ARGS 允许你捕获那些参数。它常用于宏定义的可变参数列表。

    • Log& lp = Log::getInstance();注意这行细节,我们使用引用可以避免赋值运算符。另外,我们也可以修改getInstance返回值,返回一个指针,这样也是可以实现功能的。

    • 因为FATAL定义为出现不可逆转的错误,所以采用程序结束的方式,exit(-1);

    • 对于writeLog函数的实现,我进行了规范的定义,[] : time, msg。输出结果应该如下:在这里插入图片描述
      后面将对时间功能进行重写。

    • 关于日志msg的格式输出,应该统一标准,至少需要达到这样的标准,才可以更好地在后期进行调试。
      在这里插入图片描述
      在此还要注意,buf的长度要大于我们输出的长度!!!

    源码

//Log.h
#pragma once 

#include <string>
#include <iostream>
#include <unistd.h>

#include "noncopyable.h"

enum LogLevel {
    INFO,
    ERROR,
    WARN,
    FATAL,
    DEBUG,
};

#define LOG_INFO(logmsgformat, ...)                             \
    do {                                                        \
        Log& lp = Log::getInstance();                           \
        lp.setLogLevel(INFO);                                   \
        char buf[128] = {0};                                     \
        snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
        lp.writeLog(buf);                                       \
    } while (0)

#define LOG_DEBUG(logmsgformat, ...)                            \
    do {                                                        \
        Log& lp = Log::getInstance();                           \
        lp.setLogLevel(DEBUG);                                  \
        char buf[128] = {0};                                     \
        snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
        lp.writeLog(buf);                                       \
    } while (0)

#define LOG_WARN(logmsgformat, ...)                             \
    do {                                                        \
        Log& lp = Log::getInstance();                           \
        lp.setLogLevel(WARN);                                   \
        char buf[128] = {0};                                     \
        snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
        lp.writeLog(buf);                                       \
    } while (0)

#define LOG_ERROR(logmsgformat, ...)                            \
    do {                                                        \
        Log& lp = Log::getInstance();                           \
        lp.setLogLevel(ERROR);                                  \
        char buf[128] = {0};                                     \
        snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
        lp.writeLog(buf);                                       \
    } while (0)

#define LOG_FATAL(logmsgformat, ...)                            \
    do {                                                        \
        Log& lp = Log::getInstance();                           \
        lp.setLogLevel(FATAL);                                  \
        char buf[128] = {0};                                     \
        snprintf(buf, sizeof buf, logmsgformat, ##__VA_ARGS__); \
        lp.writeLog(buf);                                       \
        exit(-1);                                               \
    } while (0)

class Log : noncopyable {
public:
    
    static Log& getInstance(); 
    void writeLog(const char* s);
    void setLogLevel(LogLevel logLevel) {
        logLevel_ = logLevel;
    }
private:
    //Log() {};
    LogLevel logLevel_;
    
};

//Log.cc
#include "Log.h"

Log& Log::getInstance() {
    static Log log;
    return log;
}


// [] : time, msg
void Log::writeLog(const char* s) {
    std::string ss;
    switch (logLevel_)
    {
    case INFO:
        ss += "[INFO] : ";
        break;
    case DEBUG:
        ss += "[DEBUG] : ";
        break;
    case ERROR:
        ss += "[ERROR] : ";
        break;
    case FATAL:
        ss += "[FATAL] : ";
        break;
    case WARN:
        ss += "[WARN] : ";
        break;
    default:
        break;
    }
    std::cout << ss << "time, " << s << std::endl;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Leetcode】240. 搜索二维矩阵 II

一、题目 1、题目描述 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性: 每行的元素从左到右升序排列。每列的元素从上到下升序排列。示例1: 输入:matrix = [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,22],[10,13,14,17,24],[18,21…

新火种AI|小冰摊牌了!大模型已获国内备案,克隆人发布箭在弦上...

作者&#xff1a;小岩 编辑&#xff1a;彩云 2024年国内AI圈的第一个重磅消息已然来袭。 1月4日&#xff0c;小冰公司宣布&#xff0c;已于去年12月成功获得“小冰大模型”的国内备案。结合此前公司在日本研发的Rinna大模型&#xff0c;小冰方面称&#xff0c;公司已实现不同…

视频会员付费系统源码 影视视频模版源码 模板PC+WAP苹果CMS影视模板源码

快猫视频会员付费视频系统/x站视频模板/苹果CMS影视模板/可打包成双端APP 适用程序&#xff1a;苹果cmsv10 兼容性和面向场景&#xff1a; 1、Windows 平台&#xff1a; IIS/Apache PHP&#xff08;5.6&#xff09; MySQL&#xff08;5.5&#xff09; 2、Linux/Unix 平台…

深度学习|4.7 参数和超参数

4.7 参数和超参数 超参数是指需要用户提前设置好的参数&#xff0c;这些超参数最终会影响到参数的数值&#xff08;相当于参数是动态调整得到的&#xff09; 学习率的选取 最优学习率应该能使得代价函数趋于一个较低的常数。

SpringBoot Import提示Cannot resolve symbol

背景 项目开发过程中经常在IDEA中出现Cannot resolve symbol&#xff0c;但是依赖确定已经通过maven或者gradle依赖了 常见原因 IDEA 存在缓存 File -> Invalidate Caches/Restart jar包的scope不正常&#xff0c;如果只是runtime则无法import&#xff0c;需要调整为com…

ssm使用web工程的相关知识

不使用框架创建web的两种方式&#xff08;这里是idea2022.3.2版&#xff09; 第一种&#xff1a;项目右键点击&#xff1a;add Framwork support选择框架进行创建。 操作步骤&#xff1a; 使用这种方式创建可能会存在的问题&#xff1a; 如果你创建web框架前&#xff1a;在…

软测如果这么学,培训班都得倒闭,直接省去上万元的学费!

俗话说外行看热闹&#xff0c;内行看门道。 写这篇文章&#xff0c;是希望把我的一些我认为是非常有价值的经验总结出来&#xff0c;能够帮助刚做测试不久的新同学&#xff0c;或者是测试经验丰富的老同学以共享。 希望我们可爱的新同学&#xff0c;准备要在测试领域耕耘的伙…

HNU-数据库系统-实验3-数据库设计

数据库系统 课程实验3数据库设计 计科210X 甘晴void 202108010XXX 目录 文章目录 数据库系统 课程实验3<br>数据库设计实验目的实验内容实验重难点实验环境实验过程&#xff08;0&#xff09;数据库需求描述&#xff08;1&#xff09;数据库概念结构设计E-R图实体图书馆…

电子电器架构网络演化 —— 车载以太网TSN

电子电器架构网络演化 —— 车载以太网TSN 我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 屏蔽力是信息过载时代一个人的特殊竞争力&#xff0c;任何消…

Weblogic安全漫谈(一)

前言 frohoff在2015年初发现commons-collections的反序列化利用链并发布了ysoserial工具[1]。9个月后&#xff0c;breenmachine对众多知名Java中间件的利用文章[2]使Java反序列化漏洞变得广为人知&#xff0c;Weblogic中首当其冲的就是大家多少都有点耳熟的T3协议反序列化。本…

家用洗地机哪款好用?洗地机品牌排行榜推荐

在如今的日常生活中&#xff0c;家用洗地机已经成为了家庭清洁中不可或缺的工具。然而&#xff0c;市面上各种不同品牌型号的洗地机让人眼花缭乱&#xff0c;让人难以选择。那么&#xff0c;家用洗地机现在买什么牌子质量好呢?为了解答这个问题&#xff0c;笔者选了几款品牌质…

Vue3+Vite打包跨平台(七牛、阿里OSS)上传部署前端项目

1、业务场景 阅读之前&#xff0c;想了解一下各位观众老爷们&#xff0c;你们公司的项目是怎么部署的&#xff1a; 1.本地打包手动上传服务器&#xff1b; 2.本地打包自动上传服务器&#xff1b; 3.代码仓库流水线自动构建&#xff1b; 4.其他…&#xff1b; 我们用的第3种部…

【Linux Shell】11. 输入/输出 重定向

文章目录 【 1. 重定向简介 】【 2. 输出重定向 】【 3. 输入重定向 】【 4. Here Document 】【 5. /dev/null 文件 】 【 1. 重定向简介 】 大多数 UNIX 系统命令从终端接受输入并将所产生的输出发送回​​到原来输入的终端。一个命令通常从标准输入的地方读取输入&#xff…

MySql8的那些不为人知的秘密揭晓

前言 MySQL 8.0 是MySQL数据库的一个重大版本更新&#xff0c;带来了许多改进和新功能。以下是MySQL 8.0的一些主要改进&#xff1a; 事务控制&#xff1a;引入了原子性、一致性、隔离性和持久性&#xff08;ACID&#xff09;的事务支持。该版本的MySQL引入了新的事务日志存储引…

Mysql大数据量下流式查询优化:Jdbc中的useFetchSize参数及其原理解析

前言 最近我朋友公司有个需求场景&#xff1a;查询千万级数据量并写入txt文件的程序优化需求。 朋友找到我对程序进行优化&#xff0c; 不然饭碗不保......&#x1f4a6; 下面就分享一下解决这个优化问题的过程和思路&#xff0c;并总结一下&#xff0c;在以后不要在踩同样的坑…

4.4 TILING FOR REDUCED MEMORY TRAFFIC

我们在CUDA中使用设备内存方面有一个内在的权衡&#xff1a;全局内存大但速度慢&#xff0c;而共享内存小但速度快。一个常见的策略是将数据划分为称为tile的子集&#xff0c;以便每个tile都适合共享内存。tile一词”借鉴了一个类比&#xff0c;即大墙&#xff08;即全局内存数…

基于协同过滤推荐的购物系统

介绍 本购物系统是一个基于协同过滤推荐算法的电商平台&#xff0c;使用 Python Django 框架、Django-simpleui 前端框架和 Vue、Element-Plus UI 组件库构建而成。该系统可根据关键词、分类等搜索筛选商品&#xff0c;并提供了个性化推荐功能&#xff0c;根据用户的历史订单、…

linux日志管理

一.inode与block 访问文件的流程&#xff1a; 根据文件夹的文件名和inode号&#xff0c;找到对应的inode表&#xff0c;再根据inode表的指针找到磁盘上的真实数据 tips&#xff1a;我磁盘空间还剩很多&#xff0c;但是无法建立文件&#xff1f; 因为inode号被分完了 解决方法&a…

交通银行网上支付接口调用测试实例

公司最近有一个网站商城项目要开始开发了&#xff0c;这几天老板和几个同事一起开着需求会议&#xff0c; 讨论了接下来的业务规划和需求策略&#xff0c;等技术需求一下来还要讨论技术需求&#xff0c; 确认后再慢慢的进入开发阶段&#xff0c;趁着闲暇时间新造的人想总结一…

C语言中常用的字符串函数(strlen、sizeof、sscanf、sprintf、strcpy)

C语言中常用的字符串函数 文章目录 C语言中常用的字符串函数1 strlen函数2 sizeof函数2.1 sizeof介绍2.2 sizeof用法 3 sscanf函数3.1 sscanf介绍3.2 sscanf用法3.3 sscanf高级用法 4 sprintf函数4.1 背景4.2 sprintf用法 5 strcpy函数5.1 strcpy介绍5.1 strcpy用法 1 strlen函…