日志

在网络设备、系统及服务程序等运作时都会产生一个叫log的事件记录;每一行日志都记载着相关信息。muduo网络库也不例外。

日志级别

日志一般有5个正常级别:

  • WARN 警告信息表明潜在错误。
  • INFO打印重要流程信息
  • ERROR错误,不影响软件正常进行
  • FATAL影响程序执行
  • DEBUG 调试信息

另外,还有两个可用的特别的日志记录级别:

  • ALL 是最低等级的,用于打开所有的日志记录
  • OFF 是最高等级的,用于关闭所有日志记录

在本项目中,仅用INFO、ERROR、FATAL、DEBUG四个级别。

Logger.h

#pragma once

#include <string>
#include "noncopyable.h"

enum LogLevel
{
   
    INFO,   //普通信息
    ERROR,  //错误信息
    FATAL,  //core信息
    DEBUG,  //调试信息
};

//输出一个日志类
class Logger: noncopyable
{
   
public:
    //获取日志唯一的实例对象
    static Logger& instance();
    //设置日志级别
    void set_logLevel(int level);
    //写日志
    void log(std::string msg);
private:
    int logLevel_;
    Logger(){
   }
};

Logger.cc

  • 其中Timestamp.h为我们自己实现的头文件,在下篇博客我会提到。
#include <iostream>
#include "logger.h"
#include "Timestamp.h"

//获取日志唯一的实例对象
Logger& Logger::instance()
{
   
    static Logger logger;
    return logger;
}

//设置日志级别
void Logger::set_logLevel(int level)
{
   
    logLevel_ = level;
}

//写日志
void Logger::log(std::string msg)
{
   
    switch(logLevel_)
    {
   
    case INFO:
        std::cout << "[INFO]";
        break;
    case ERROR:
        std::cout << "[ERROR]";
        break;
    case FATAL:
        std::cout << "[FATAL]";
        break;
    case DEBUG:
        std::cout << "[DEBUG]";
        break;
    default:
        break;
    }

    //打印时间和信息msg
    std::cout << Timestamp::now().toString() << ":"<< msg<< std::endl;
}

Logger使用

这些代码直接放在Logger.h文件中即可。

// LOG_INFO("%s %d",arg1,arg2)
//宏代码换行之后需要接续符
//##__VA_ARGS_一个可变参数
#define LOG_INFO(LogmsgFormat,...)\ do \ { \ Logger& logger = Logger::instance();\ logger.setlogLevel(INFO);\ char buf[1024] = {0};\ snprintf(buf, 1024, LogmsgFormat,##__VA_ARGS__);\ logger.log(buf);\ }while (0)

#define LOG_ERROR(LogmsgFormat,...)\ do \ { \ Logger& logger = Logger::instance();\ logger.setlogLevel(ERROR);\ char buf[1024] = {0};\ snprintf(buf, 1024, LogmsgFormat,##__VA_ARGS__);\ logger.log(buf);\ }while (0) 

#define LOG_FATAL(LogmsgFormat,...)\ do \ { \ Logger& logger = Logger::instance();\ logger.setlogLevel(FATAL);\ char buf[1024] = {0};\ snprintf(buf, 1024, LogmsgFormat,##__VA_ARGS__);\ logger.log(buf);\ }while (0)

//因为调试信息很多,影响我们
//默认是给关闭的

#ifdef MUDEBUG
#define LOG_DEBUG(LogmsgFormat,...)\ do \ { \ Logger& logger = Logger::instance();\ logger.setlogLevel(DEBUG);\ char buf[1024] = {0};\ snprintf(buf, 1024, LogmsgFormat,##__VA_ARGS__);\ logger.log(buf);\ }while (0)
#else
    #define LOG_DEBUG(LogmsgFormat,...)
#endif

参考文献

[1] 施磊.重写moduo库.图论科技.2020.7.