日志用于记录程序的执行记录包括程序的出错记录,程序致命退出原因,程序的正常执行记录。这样我们就可以很快的察觉程序的错误原因、执行状况等等,因此管理日志信息是非常重要的。
日志一般由以下部分组合:
日志时间、日志等级、日志内容、日志文件的名称
日志等级分为5个:Info:常规信息、Warning:报警信息、Error:发生错误,需要立即处理、Fatal:致命信息、Debug:调试信息
学习一下多参数函数相关的c接口:
#include <iostream>
#include <stdarg.h>
int argfunc(int n, ...)//n是要相加的元素个数,...代表要传入的参数
{va_list s;//s相当于一个int*类型的指针va_start(s, n);//s=&n+1int sum=0;while(n--){sum += va_arg(s, int);}va_end(s);//将s置为空return sum;
}
int main()
{int a= argfunc(3,1,2,3);std::cout<<a<<std::endl;return 0;
}
vsnprintf函数
利用多参数相关接口,就可以实现对函数进行动态参数传参!
time函数
localtime函数
localtime函数的返回值是一个struct tm结构体类型的指针,struct tm结构体里储存了对应时间戳的年月日时分秒,如下就是struct tm结构体:
具体代码实现如下:
log.hpp
#pragma once
#include <iostream>
#include <string>
#include <ctime>
#include <cstdio>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>#define Screen 1 // 表示向显示器上打印日志信息
#define Onefile 2 // 表示向logtxt日志文件里写日志信息(没有该日志文件open函数会自动创建)
#define Classfile 3 // 对向指定等级的日志文件写内容,比如:Fatal等级的日志信息写到logtxt.Fatal日志文件中#define Size 1024
#define Logfile "log.txt"class Log
{
public:Log(int n = 1): printmethod(n), path("./log/"){}void printLogtxt(const std::string &s, const char *logtxt){switch (printmethod){case Screen:std::cout << logtxt;break;case Onefile:printOneFile(Logfile, logtxt);break;case Classfile:printClassFile(s, logtxt);break;default:break;}}void printOneFile(const std::string &Logname, const std::string& logtxt){std::string _s = path + Logname; // 给logtxt文件加上我们路径,方便我们以后再该路径里管理日志文件int fd = open(_s.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0666);if (fd < 0){perror("open");return;}write(fd, logtxt.c_str(), logtxt.size());close(fd);}void printClassFile(const std::string &s, const char *logtxt){std::string _s(Logfile);_s+= ".";_s+= s;printOneFile(_s, logtxt);}void operator()(const std::string &str, const char *format, ...){time_t t = time(nullptr);struct tm *ctime = localtime(&t);char str1[Size] = {0};snprintf(str1, sizeof(str1), "[%s][%d-%d-%d:%d:%d:%d]", str.c_str(), ctime->tm_year + 1900,ctime->tm_mon + 1, ctime->tm_mday,ctime->tm_hour, ctime->tm_min, ctime->tm_sec);va_list s;va_start(s, format);char str2[Size] = {0};vsnprintf(str2, sizeof(str2), format, s); // format是格式字符串 s是多参数...的第一个字符串地址va_end(s);char logtxt[2 * Size] = {0};snprintf(logtxt, sizeof(logtxt), "%s %s\n", str1, str2);printLogtxt(str, logtxt);}private:int printmethod;std::string path; // 日志文件将来被创建时所在的路径,更有利于我们管理日志文件
};
testlog.cpp
#include "log.hpp"
#include <errno.h>
#include <cstring>
#include <vector>
int main()
{Log log(3);log("Info", "向%s日志文件里写入内容成功!", "log.txt.Info");std::vector<int> v = {1,2};if(!v.empty())log("Debug", "v.size() is %d", v.size());return 0;
}
在log目录下生成的log.txt.Info文件:
在log目录下生成的log.txt.Debug文件: