当前位置:   article > 正文

波奇学Linux:日志

波奇学Linux:日志

日志信息

日志:日志时间+日志等级+日志内容+文件的名称和代号

日志等级示范:Info:常规消息

                          Warning:报警信息

                           Error:必要严重了,可能要立即处理

                           Fatal:致命的

                            Debug:调试

日志时间获取

  1. time_t t= time(nullptr);// 获取时间戳
  2. struct tm* ctime=localtime(&t);// 将时间戳转换为年月日
  3. //tm是个结构体,里面保存时间戳转换的年月日
  4. //打印时间
  5. printf("[%s][%d-%d-%d %d:%d:%d]",levelToString(level).c_str(),\
  6. ctime->tm_year+1900,ctime->tm_mon+1,ctime->tm_mday,\
  7. ctime->tm_hour,ctime->tm_min,ctime->tm_sec)

 

注意点:

tm->year是从1900年开始算所以要加上1900,月份从0开始算tm_mon+1

levetToString是将int转换成string类型

 日志等级处理

defin 信息的值,再转变成%s方便打印

  1. #define Info 0
  2. #define Debug 1
  3. #define Warning 2
  4. #define Error 3
  5. #define Fatal 4
  6. #define Size 1024
  7. std::string levelToString(int level)
  8. {
  9. switch(level)
  10. {
  11. case Info:return "Info";
  12. case Debug: return "Debug";
  13. case Warning: return "Debug";
  14. case Error: return "Debug";
  15. case Fatal: return "Debug";
  16. default: return "None";
  17. }
  18. }

 处理可变参数

  1. //n 表示前两个参数,当参数数量大于n时,只算从左到右的两个,参数从右往左压栈
  2. int sum(int n,...)
  3. {
  4. va_list s;//char* 类型指针帮助我们找到可变类型参数
  5. va_start(s,n); //让 s指向n的地址 s=&n+1
  6. //va_start是宏
  7. // 可变参数至少有一个具体的实参、
  8. int sum=0;
  9. while(n)
  10. {
  11. sum+=va_arg(s,int);//s指向的可变参数类型,int表示参数类型 ,每次返回一个值
  12. n--;
  13. }
  14. va_end(s);//使得s为nullptr
  15. return sum;
  16. }

 视解图

 s=&n+1// 可变参数需要一个实参来确定位置,参数压栈是从左往右的

 消息函数代码实现

  1. // level表示等级,format表示格式,...表示日志等级
  2. void logmessage(int level,char* format, ...)
  3. {
  4. char leftbuffer[Size];
  5. time_t t= time(nullptr);// 获取时间戳
  6. struct tm* ctime=localtime(&t);// 将时间戳转换为年月日
  7. //snpritf,后面的参数和printf类似,按某种格式输出参数,前面是输出位置,输入到数组leftbuffer中
  8. snprintf(leftbuffer,sizeof(leftbuffer),"[%s][%d-%d-%d %d:%d:%d]",levelToString(level).c_str(),\
  9. ctime->tm_year+1900,ctime->tm_mon+1,ctime->tm_mday,\
  10. ctime->tm_hour,ctime->tm_min,ctime->tm_sec);
  11. va_list s;// va_list就是封装的char*
  12. va_start(s,format);//s=&format+1
  13. char rightbuffer[Size];
  14. //vsnprinft,用来处理可变参数,后面的参数和printf类似,按某种格式输出参数,前面是输出位置,输入到数组righttbuffer中
  15. vsnprintf(rightbuffer,sizeof(rightbuffer),format,s);//传入一个s指向第一个可变参数的指针
  16. // 默认部分+自定义部分
  17. char logtxt[Size*2];
  18. //拼接字符串
  19. snprintf(logtxt,sizeof(logtxt),"%s %s\n",leftbuffer,rightbuffer);
  20. printf("%s",logtxt);
  21. }

 运用示例:代替perror

日志输入到文件

  1. class Log
  2. {
  3. public:
  4. Log()
  5. {
  6. printMethod=Screen;
  7. path="./log/";
  8. }
  9. void Enable(int method)
  10. {
  11. printMethod=method;
  12. }
  13. std::string levelToString(int level)
  14. {
  15. ......
  16. }
  17. void logmessage(int level,char* format, ...)
  18. {
  19. ......
  20. printLog(level,logtxt);
  21. }
  22. void printLog(int level,const std::string& logtxt)
  23. {
  24. switch(printMethod)
  25. {
  26. case Screen:
  27. std::cout<<logtxt<<std::endl;
  28. break;
  29. case Onefile:
  30. printOneFile(LogFile,logtxt);
  31. break;
  32. case Classfile:
  33. printClassFile(level,logtxt);
  34. break;
  35. default:
  36. break;
  37. }
  38. }
  39. void printOneFile(const std::string& logname,const std::string& logtxt)
  40. {
  41. std::string _logname=path+logname;
  42. //打开创建文件
  43. int fd=open(_logname.c_str(), O_WRONLY|O_CREAT|O_APPEND,0666);
  44. if(fd<0) return ;
  45. write(fd,logtxt.c_str(),logtxt.size());
  46. close(fd);
  47. }
  48. void printClassFile(int level,const std::string &logtxt)
  49. {
  50. //将Warning/Fatal等分开
  51. std::string filename = LogFile;
  52. filename+=".";
  53. filename+=levelToString(level); //"log.txt.Debug/Warning/Fatal"
  54. printOneFile(filename,logtxt);
  55. }
  56. ~Log()
  57. {}
  58. private:
  59. int printMethod; //确定输出位置
  60. std::string path; //输出地址
  61. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/176555
推荐阅读
相关标签
  

闽ICP备14008679号