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

[项目][WebServer][日志设计]详细讲解

目录

  • 0.前言
  • 1.实现一[Base]
  • 2.实现二[Pro]


0.前言

  • 本篇给出两种日志设计形式
    • 第一种较为简单,但较为直接,功能比较单一
    • 第二种相对复杂一些,但用起来类似于printf,功能更灵活些
  • 注意:两种实现中,都是用了条件编译,以便屏蔽或观察调试信息

1.实现一[Base]

  • 说明:
    • 日志是需要日志等级的,所以用宏来区别等级
    • 一般日志需要以下内容
      • 日志等级
      • 日志输出内容
      • 所在文件、所在行,以便排错
  • void Log(string level, string msg, string file_name, int line),函数参数过多,每次调用都要手动输入__FILE__ __LINE__,为了简化使用,做以下处理
    • 用宏代替函数,减少固定的传参输入 —> file_name && line
    • 但是level是int类型,无法传给string
      • **#**可以把一个宏参数变成对应的字符串
    • #define LOG(level, msg) Log(#level, msg, __FILE__, __LINE__)
#include <iostream>
#include <string>
#include <ctime>

#define DEBUG   0
#define INFO    1
#define WARNING 2
#define ERROR   3
#define FATAL   4

void Log(std::string level, std::string msg, std::string file_name, int line)
{
#ifndef DEBUG_SHOW
    if(level == "DEBUG")
    {
        return;
    }
#endif
    std::cout << "[" << level << "][" << time(nullptr) << "][" << msg \
		    << "][" << file_name << "]["<< line << "]" << std::endl;
}

2.实现二[Pro]

  • 该种实现使用了可变参数列表,使其用起来和printf()一样
#include <iostream>
#include <cstdarg>
#include <ctime>

// 日志是有日志级别的
#define DEBUG   0
#define NORMAL  1
#define WARNING 2
#define ERROR   3
#define FATAL   4

// 映射表
const char *gLevelMap[] =
{
    "DEBUG",
    "NORMAL",
    "WARNING",
    "ERROR",
    "FATAL"
};

#define LOGFILE "./threadpool.log"

// 完整的日志功能,至少要包括:
// 日志等级 时间 支持用户自定义(日志内容 文件行 文件名)
void LogMessage(int level, const char *format, ...)
{
#ifndef DEBUG_SHOW
    if(level == DEBUG)
    {
        return;
    }
#endif

    char stdBuffer[1024]; // 标准部分
    time_t timestamp = time(nullptr);
    snprintf(stdBuffer, sizeof stdBuffer, "[%s] [%ld]", gLevelMap[level], timestamp);

    char logBuffer[1024]; // 自定义部分
    va_list args;
    va_start(args, format);
    vsnprintf(logBuffer, sizeof logBuffer, format, args);
    va_end(args);

    printf("%s %s\n", stdBuffer, logBuffer);
}

http://www.kler.cn/a/303996.html

相关文章:

  • 【juc】AbstractQueuedSynchronized为什么采用双向链表
  • 单例模式详解:如何优雅地实现线程安全的单例
  • 详解kafka消息发送重试机制的案例
  • 回归分析学习
  • 河南省的一级科技查新机构有哪些?
  • 三种单例实现
  • 【JVM 工具命令】JAVA程序线上问题诊断,JVM工具命令的使用,jstat, jstack,jmap命令的使用
  • 【机器学习】使用Numpy实现神经网络训练全流程
  • 关于若依flowable的安装
  • 76-mysql的聚集索引和非聚集索引区别
  • 为什么网站加载速度总是那么不尽如人意呢?(网站优化篇)
  • 2024.9.14(RC和RS)
  • Docker操作MySQL
  • 互联网环境下CentOS7部署K8S
  • LNMP的简单安装(ubuntu)
  • Artec Leo协助定制维修管道,让石油和天然气炼油厂不停产
  • vue3开发uniapp转字节小程序注意事项
  • 《C++PrimerPlus》第10章:类和对象
  • go语言开发windows抓包工具
  • 在centos上搭建syslog服务端
  • 详情攻略来了!浏览网站记录怎么查?一文读懂这3种实用方法
  • Vue3 响应式工具函数isRef()、unref()、isReactive()、isReadonly()、isProxy()
  • 火焰检测算法、明烟明火检测、烟火检测算法
  • dirty pages , swapiness 查看SWAP占用进程
  • 线性代数 第六讲 特征值和特征向量_相似对角化_实对称矩阵_重点题型总结详细解析
  • 【原创】java+springboot+mysql疫情期间在线答疑系统设计与实现