目录
一.日志
日志等级,日志时间,日志内容,文件的名称和行号
日志等级:
Info:常规消息
Warning:报警消息
Error:错误,可能需要立即处理
Fatal:致命的
Debug:调试
二.实现任意个数元素求和
使用可变参数要使用若干个宏定义,这些宏定义在:
cpp
//使用可变参数时一定要有一个具体的参数
int Sum(int n, ...)
{
//用来提取可变参数的一个个参数,其实本质上就是一个char*类型的指针变量
va_list s;
//只向可变参数的首地址,内部封装了s = &n + 1;
va_start(s, n);
//实现求和
int sum = 0;
while(n)
{
//根据类型提取参数
va_arg(s, int);
n--;
}
//s = NULL;
va_end(s);
return sum;
}
主函数调用:
此时我们传入的可变参数都是相同的类型的,如果传入不同的类型的话,就要像printf一样做获取的字符串处理。
三.编写一个日志函数
**1.**设置日志等级
cpp
#define Info 0
#define DeBug 1
#define Warning 2
#define Error 3
#define Fatal 4
//实现日志函数
void logmessage(int level, char* formatr, ...)
{
}
2.设置日志时间
a.Linux中获取时间戳的函数
b.Linux中转换时间戳的函数
会将得到的时间戳转换为以下形式: 因为年和月都是从0开始计的所以在打印的时候,需要加1900和1。
cpp
void logmessage(int level, char* formatr, ...)
{
//获取时间戳
time_t t = 0;
time(&t);
//转换时间戳
struct tm* ctime = NULL;
ctime = localtime(&t);
//打印获取到的时间
printf("%d-%d-%d %d:%d:%d\n"
, ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday
, ctime->tm_hour, ctime->tm_min, ctime->tm_sec);
}
3.设置日志的打印格式
默认部分 + 自定义部分
cpp
#define Info 0
#define DeBug 1
#define Warning 2
#define Error 3
#define Fatal 4
#define Log_buffer_SIZE 1024
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 logmessage(int level, char* format, ...)
{
//获取日志的等级
string level_str;
level_str = levelToString(level);
//获取时间戳
time_t t = 0;
time(&t);
//转换时间戳
struct tm* ctime = NULL;
ctime = localtime(&t);
// //打印获取到的时间
// printf("%d-%d-%d %d:%d:%d\n"
// , ctime->tm_year + 1900, ctime->tm_mon + 1, ctime->tm_mday
// , ctime->tm_hour, ctime->tm_min, ctime->tm_sec);
//整合日志的默认部分
char leftbuffer[Log_buffer_SIZE];
snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d] : " ,level_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 rightbuffer[Log_buffer_SIZE];
vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
va_end(s);
//整合默认部分和自定义部分
char logtxt[Log_buffer_SIZE * 2];
snprintf(logtxt, sizeof(logtxt), "%s%s\n", leftbuffer, rightbuffer);
printf("%s", logtxt);
}
4.将日志的内容输出到文件
cpp
#include <time.h>
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <fcntl.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
using namespace std;
#define Info 0
#define DeBug 1
#define Warning 2
#define Error 3
#define Fatal 4
#define Log_buffer_SIZE 1024
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";
}
}
#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;
}
void printLog(int level, const string& logtxt)
{
switch (printMethod)
{
case Screen:
cout << logtxt.c_str() << endl;
break;
case Onefile:
printOneFile(LogFile, logtxt);
break;
case Classfile:
printClassFile(level, logtxt);
break;
default:
break;
}
}
void printOneFile(const string &logname, const string &logtxt)
{
string _logname = path;
_logname += 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 string &logtxt)
{
string filename = LogFile;
filename += ".";
filename += levelToString(level); // "log.txt.Debug/Warning/Fatal"
printOneFile(filename, logtxt);
}
~Log()
{
}
//处理日志等级
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 operator()(int level, char *format, ...)
{
// 获取日志的等级
string level_str;
level_str = levelToString(level);
// 获取时间戳
time_t t = 0;
time(&t);
// 转换时间戳
struct tm *ctime = NULL;
ctime = localtime(&t);
// 整合日志的默认部分
char leftbuffer[Log_buffer_SIZE];
snprintf(leftbuffer, sizeof(leftbuffer), "[%s][%d-%d-%d %d:%d:%d] : ", level_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 rightbuffer[Log_buffer_SIZE];
vsnprintf(rightbuffer, sizeof(rightbuffer), format, s);
va_end(s);
// 整合默认部分和自定义部分
char logtxt[Log_buffer_SIZE * 2];
snprintf(logtxt, sizeof(logtxt), "%s%s\n", leftbuffer, rightbuffer);
// printf("%s", logtxt);
printLog(level, logtxt);
}
private:
int printMethod;
string path;
};