1. 日志要求
对于一个日志来说,我们任认为其应该具有以下的内容
1. 日志时间
2. 日志等级
3. 日志内容
4. 文件名称与行号
在此基础上我们对不同的日志做出分级,即
info: 常规信息
warning: 报警信号
error: 严重信号,可能需要立即处理
fatal: 致命信号
Debug: 调试信息
2. 代码实现
#pragma once#include <iostream>
#include <time.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>#define SIZE 1024#define Info 0
#define Debug 1
#define Warning 2
#define Error 3
#define Fatal 4#define Screen 1
#define Onefile 2
#define Classfile 3#define LogFile "log.txt"class Log
{
public:// 构造函数Log(){// 设置默认日志模式为向屏幕打印printMethod = Screen;path = "./log/";}// 调整日志模式void Enable(int method){printMethod = method;}// 返回分级字符串std::string levelToString(int level){switch (level){case Info:return "Info";case Debug:return "Debug";case Warning:return "Warning";case Error:return "Error";case Fatal:return "Fatal";default:return "None";}}// 根据不同模式,向不同位置打印日志void printLog(int level, const std::string &logtxt){switch (printMethod){case Screen:std::cout << logtxt;break;case Onefile:printOneFile(LogFile, logtxt);break;case Classfile:printClassFile(level, logtxt);break;default:break;}}// 向一个文件中写入日志void printOneFile(const std::string &logname, const std::string &logtxt){std::string _logname = path + logname;int fd = open(_logname.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666); // "log.txt"if (fd < 0)return;write(fd, logtxt.c_str(), logtxt.size());close(fd);}// 向一个文件夹中写入日志void printClassFile(int level, const std::string &logtxt){std::string filename = LogFile;filename += ".";filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"printOneFile(filename, logtxt);}~Log(){}// 运算符重载 便于直接使用void operator()(int level, const char *format, ...){time_t t = time(nullptr);struct tm *ctime = localtime(&t);// leftbuffer - 存储等级信息与日期信息char leftbuffer[SIZE];snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d]", levelToString(level).c_str(),ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday,ctime->tm_hour, ctime->tm_min, ctime->tm_sec);// 将可变参数中传入的参数写入到rightbuffer中// rightbuffer - 存储用户提示va_list s;va_start(s, format);char rightbuffer[SIZE];vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);va_end(s);// 格式:默认部分+自定义部分char logtxt[SIZE * 2];snprintf(logtxt, sizeof(logtxt), "%s %s\n", leftbuffer, rightbuffer);printLog(level, logtxt);}private:int printMethod;std::string path;
};
3. 使用测试
#include "Log.hpp"int main()
{// 创建Log对象Log lg;lg(Info, "启动成功");sleep(1);lg(Debug, "这是一个调试信息");sleep(1);lg(Warning, "这是一个警告信息");sleep(1);lg(Error, "这是一个错误信息");sleep(1);lg(Fatal, "这是一个致命错误信息");return 0;
}
测试效果