文章目录
前言
我们这个设计的日志可以自定以输出的方向,可以向显示器打印错误信息,也可以向指定目录写入,或者是分类写入
一、 目录实现(log.hpp)
#pragmaonce#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>#defineSIZE1024//对错误等级进行分级#defineInfo0#defineDebug1#defineWarning2#defineError3#defineFatal4//将错误信息打入到什么位置#defineScreen1#defineOnefile2#defineClassfile3//存储错误信息的文件默认名字#defineLogFile"log.txt"usingnamespace std;classLog{public:Log(){//默认打印方式往显示屏//规定好默认路径
printMethod=Screen;
path="./log/";}//自己改变默认答应方式voidEnable(int method){
printMethod=method;}//将错误等级转换为字符串的形式
string levelTostring(int level){switch(level){case Info:return"Info";case Debug:return"Debuf";case Warning:return"Warning";case Error:return"Error";case Fatal:return"Fatal";default:return"None";}}//根据传出的信息,生成字符串logtxt,这个字符串中就是错误信息voidoperator()(int level,constchar*format,...){//报错信息 格式:默认部分+自定义部分
time_t t =time(nullptr);structtm*ctime =localtime(&t);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);
va_list s;va_start(s, format);//leftbuffer为获取的报错时间字符串,为默认部分//rightbuffer为我们的自定义部分char rightbuffer[SIZE];vsnprintf(rightbuffer,sizeof(rightbuffer), format, s);va_end(s);//将leftbuffer 与rightbuffer合并成字符串logtxt//这就是我们的报错的错误信息char logtxt[SIZE *2];snprintf(logtxt,sizeof(logtxt),"%s %s\n", leftbuffer, rightbuffer);//将错误信息按指定方式打印到指定地方printLog(level, logtxt);}//将错误信息按指定方式打印到指定地方voidprintLog(int level,const string &logtxt){switch(printMethod){case Screen://打印到屏幕
cout<<logtxt<<endl;case Onefile://打印到一个文件printOnefile(LogFile,logtxt);break;case Classfile://分错误信息打印到不同文件printClassfile(level,logtxt);break;default:break;}}voidprintOnefile(const string logname,const string logtxt){// printOnefile(LogFile,logtxt);
string _logname=path+logname;// ./log/log.txtint fd=open(_logname.c_str(),O_WRONLY|O_CREAT|O_APPEND,0666);if(fd<0)return;write(fd,logtxt.c_str(),logtxt.size());close(fd);}voidprintClassfile(int level,const string logtxt){// printClassfile(level,logtxt);
string filename=LogFile;
filename+=".";
filename+=levelTostring(level);// log.txt. (string)level//设置好文件名字后,再用单文件的打印方式写入文件printOnefile(filename,logtxt);}private:int printMethod;//打印方法
string path;//打印路径};
二、目录的具体使用
这里我们以命名管道之间两个进程传递信息为场景使用这个日志功能
1.comm.hpp(管道初始化)
#pragmaonce#include<iostream>#include<string>#include<sys/types.h>#include<sys/stat.h>#include<unistd.h>#include<cerrno>#include<string.h>#include<fcntl.h>//命名管道的名字与路径#defineFIFO_FILE"./myfifo"#defineMODE0664//返回的错误码enum{
FIFO_CREAT_ERR=1,
FIFO_DELETE_ERR,
FIFO_OPEN_ERR
};//采用Init类,类似智能指针,我们在析构函数中调用删除命名管道的函数//程序结束会自动调用析构函数classInit{public:Init(){int n=mkfifo(FIFO_FILE,MODE);if(n==-1){perror("mkfifo");exit(FIFO_CREAT_ERR);}}~Init(){int m=unlink(FIFO_FILE);if(m==-1){perror("unlink");exit(FIFO_DELETE_ERR);}}};
2.sever.cpp(为读端且令其创建命名管道)
#include"comm.hpp"#include"log.hpp"usingnamespace std;// 管理管道文件intmain(){
Init init;//创建命名管道
Log log;
log.Enable(Onefile);//重定向错误信息打入位置// 打开管道int fd =open(FIFO_FILE, O_RDONLY);if(fd <0){//如果有错就打印错误信息log(Fatal,"error string: %s, error code: %d",strerror(errno), errno);exit(FIFO_OPEN_ERR);}log(Info,"server open file done, error string: %s, error code: %d",strerror(errno), errno);log(Warning,"server open file done, error string: %s, error code: %d",strerror(errno), errno);log(Fatal,"server open file done, error string: %s, error code: %d",strerror(errno), errno);log(Debug,"server open file done, error string: %s, error code: %d",strerror(errno), errno);// 开始通信while(true){char buffer[1024]={0};int x =read(fd, buffer,sizeof(buffer));if(x >0){
buffer[x]=0;
cout <<"client say# "<< buffer << endl;}elseif(x ==0){log(Debug,"client quit, me too!, error string: %s, error code: %d",strerror(errno), errno);break;}elsebreak;}close(fd);return0;}
3.client.cpp(为写端)
#include<iostream>#include"comm.hpp"usingnamespace std;intmain(){int fd =open(FIFO_FILE, O_WRONLY);//打开管道if(fd <0){perror("open");exit(FIFO_OPEN_ERR);}
cout <<"client open file done"<< endl;
string line;while(true){
cout <<"Please Enter@ ";getline(cin, line);//因为可能有空格,cin不读入空格write(fd, line.c_str(), line.size());}close(fd);return0;}
本文转载自: https://blog.csdn.net/m0_74774759/article/details/134632824
版权归原作者 Kaugo 所有, 如有侵权,请联系我们删除。
版权归原作者 Kaugo 所有, 如有侵权,请联系我们删除。