基于FIFO的c++多进程log封装

 1 #ifndef PROCESS_LOG_H
 2 #define PROCESS_LOG_H
 3 
 4 #include <string>
 5 #include <sstream>
 6 #include <cstring>
 7 
 8 #include <fcntl.h>
 9 #include <sys/stat.h>
10 #include <sys/types.h>
11 #include<sys/time.h>
12 #include<unistd.h>
13 
14 using std::string;
15 
16 #define LOG_KIND_FILE_NAME 1
17 #define LOG_KIND_FIFO_NAME 2
18 
19 #define LOG_ERROR_OPEN_FILE 1
20 #define LOG_ERROR_MKFIFO 2
21 #define LOG_ERROR_OPEN_FIFO 3
22 #define LOG_ERROR_FORK 4
23 #define LOG_ERROR_WRITE 5
24 
25 class Log
26 {
27 private:
28     string _log_file_name;
29     string _log_fifo_name;
30     int _log_file_fd;
31     int _log_fifo_fd;
32 public:
33     Log();
34     Log & bind(int kind, string s);
35     void start();
36     void stop();
37     void add(int pid, string s);
38     ~Log();
39 };
40 
41  inline string getTime(void);
42 
43 #endif
View Code

log.cpp:

  1 #include "log.h"
  2 
  3 //TODO  Log构造函数
  4 Log::Log(/* args */) : _log_fifo_name(""),
  5     _log_file_fd(-1),
  6     _log_file_name("")
  7 {
  8 }
  9 
 10 //TODO Log析构函数
 11 Log::~Log()
 12 {
 13     //释放文件
 14     if(_log_file_fd>0){
 15         close(_log_file_fd);
 16     }
 17     if(_log_fifo_fd > 0){
 18         close(_log_fifo_fd);
 19     }
 20 }
 21 
 22 //TODO 设置Log的属性(log文件名、FIFO文件名)
 23 Log & Log::bind(int kind, string s)
 24 {
 25     switch (kind)
 26     {
 27     case LOG_KIND_FILE_NAME:
 28         this->_log_file_name = s;
 29         break;
 30     case LOG_KIND_FIFO_NAME:
 31         this->_log_fifo_name = s;
 32         break;
 33     default:
 34         throw -1;
 35         break;
 36     }
 37     return *this;
 38 }
 39 
 40 //TODO 添加日志
 41 void Log::add(int pid, string s)
 42 {
 43     //构造日志格式[pid time] info
 44     std::stringstream ss;
 45     ss << "[" << pid << " " << getTime() << "]" << s;
 46     s = ss.str();
 47     //写入fifo
 48     write(this->_log_fifo_fd, s.c_str(), s.length());
 49 }
 50 
 51 //TODO 停止Log
 52 void Log::stop()
 53 {
 54     if(write(this->_log_fifo_fd, "STOP",  4) < 0){
 55         throw LOG_ERROR_WRITE;
 56     }
 57 }
 58 
 59 //TODO 启动Log进程
 60 void Log::start()
 61 {
 62     if(mkfifo(this->_log_fifo_name.c_str(), 0777) != 0){
 63         throw LOG_ERROR_MKFIFO;
 64     }
 65 
 66     //打开log文件
 67     this->_log_file_fd = open(this->_log_file_name.c_str(), O_WRONLY);
 68     if(_log_file_fd < 0){
 69         throw LOG_ERROR_OPEN_FILE;
 70     }
 71     
 72     //创建进程
 73     int fid = fork();
 74     //原进程
 75     if(fid > 0 ){
 76         //只写方式打开fifo
 77         this->_log_fifo_fd = open(this->_log_fifo_name.c_str(), O_WRONLY);
 78         if(this->_log_fifo_fd <= 0){
 79             throw LOG_ERROR_OPEN_FIFO;
 80         }
 81         return ;
 82     } 
 83     //log进程
 84     else if( fid == 0){
 85         //只读方式打开fifo
 86         this->_log_fifo_fd = open(this->_log_fifo_name.c_str(), O_RDONLY);
 87         if(this->_log_fifo_fd <= 0){
 88             throw LOG_ERROR_OPEN_FIFO;
 89         }
 90 
 91         //Loop
 92         bool stop_flag = false;
 93         while (!stop_flag)
 94         {
 95             //读取fifo
 96             char buf[1024];
 97             int len = read(this->_log_fifo_fd, buf, 1023);
 98             if(len <= 0){
 99                 continue;
100             }
101             buf[len] = '';
102 
103             //停止
104             if(strcasecmp("STOP",  buf) == 0){
105                 stop_flag = true;
106             }
107             //写入log
108             if(write(this->_log_file_fd, buf, len) < 0){
109                 throw LOG_ERROR_WRITE;
110             }
111 
112             //刷新文件
113             sync();
114         }
115         //退出进程
116         exit(0);
117         
118     } else {
119         throw LOG_ERROR_FORK;
120     }
121 }
122 
123     // TODO: 获取时间
124  inline string getTime(void)
125 {
126     timeval tv;
127     tm * time;
128    std::stringstream ss;
129 
130     if(gettimeofday(&tv, nullptr) == -1){
131       throw errno;
132     }
133      time = localtime(&(tv.tv_sec));
134     char systime[40];
135     strftime(systime, 40, "%Y-%m-%d %H:%M:%S.",  time);
136         
137     ss << systime << (int64_t)(tv.tv_usec / 1000);
138         
139     return ss.str();
140 }
View Code
原文地址:https://www.cnblogs.com/HadesBlog/p/13173270.html