码迷,mamicode.com
首页 > 编程语言 > 详细

简单的C/C++日志模块实现

时间:2017-09-26 00:03:45      阅读:201      评论:0      收藏:0      [点我收藏+]

标签:class   amp   ring   syslog   size   附加   实现   fda   log4c   

诸如log4cxx之类的日志库还是有些复杂,自己实现了一个简单的日志模块。

支持文件设置、日志级别、非原子打印,还附加了常用的线程锁相关宏,如下:

sys_logger.h

  1 #ifndef __sys_logger_h_
  2 #define __sys_logger_h_
  3 
  4 #include <stdio.h>
  5 #include <iostream>
  6 #include <cstring>
  7 #include <stdarg.h>
  8 #include <time.h>
  9 #include <unistd.h>
 10 #include <pthread.h>
 11 #include <sys/time.h>
 12 #include <sys/syscall.h>
 13 
 14 #define gettid() syscall(SYS_gettid)
 15 
 16 #define LEVEL_SOCKET_DEBUG  0
 17 #define LEVEL_DEBUG         1
 18 #define LEVEL_INFO          2
 19 #define LEVEL_WARNING       3
 20 #define LEVEL_ERROR         4
 21 
 22 #define LOG_BUF_SIZE        2048
 23 #define MAX_FILENAME_LEN    256
 24 
 25 
 26 using namespace std;
 27 
 28 #define LOG_INFO_NOLOCK(format, ...)  29     SysLogger::GetInstance()->WriteLogNoLock(LEVEL_INFO,  30                                         __FILE__, __LINE__, gettid(),  31                                         format, ##__VA_ARGS__)
 32 
 33 #define SOCKET_DEBUG(format, ...)  34     SysLogger::GetInstance()->WriteLog(LEVEL_SOCKET_DEBUG,  35                                         __FILE__, __LINE__, gettid(),  36                                         format, ##__VA_ARGS__)
 37     
 38 #define LOG_DEBUG(format, ...)  39     SysLogger::GetInstance()->WriteLog(LEVEL_DEBUG,  40                                         __FILE__, __LINE__, gettid(),  41                                         format, ##__VA_ARGS__)
 42     
 43 #define LOG_INFO(format, ...)  44     SysLogger::GetInstance()->WriteLog(LEVEL_INFO,  45                                         __FILE__, __LINE__, gettid(),  46                                         format, ##__VA_ARGS__)
 47     
 48 #define LOG_WARNING(format, ...)  49     SysLogger::GetInstance()->WriteLog(LEVEL_WARNING,  50                                         __FILE__, __LINE__, gettid(),  51                                         format, ##__VA_ARGS__)
 52     
 53 #define LOG_ERROR(format, ...)  54     SysLogger::GetInstance()->WriteLog(LEVEL_ERROR,  55                                         __FILE__, __LINE__, gettid(),  56                                         format, ##__VA_ARGS__)
 57 
 58 // Pthread trylock, lock, unlock
 59 #define MUTEX_LOCK(mutex) {int oldstate; 60             pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 61             pthread_mutex_lock(mutex); 62             pthread_setcancelstate(oldstate, NULL); 63 }
 64 
 65 #define MUTEX_UNLOCK(mutex) {int oldstate; 66             pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 67             pthread_mutex_unlock(mutex); 68             pthread_setcancelstate(oldstate, NULL); 69 }
 70 
 71 inline int MutexTryLock(pthread_mutex_t* mutex)
 72 {
 73     int ret = 0;
 74     int oldstate;
 75     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 76     ret = pthread_mutex_trylock(mutex);
 77     pthread_setcancelstate(oldstate, NULL);
 78     return ret;
 79 }
 80 
 81 inline void MutexLock(pthread_mutex_t* mutex)
 82 {
 83     int oldstate;
 84     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 85     pthread_mutex_lock(mutex);
 86     pthread_setcancelstate(oldstate, NULL);
 87 }
 88 
 89 inline void MutexUnlock(pthread_mutex_t* mutex)
 90 {
 91     int oldstate;
 92     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate);
 93     pthread_mutex_unlock(mutex);
 94     pthread_setcancelstate(oldstate, NULL);
 95 }
 96 
 97 class SysLogger
 98 {
 99 public:
100     SysLogger();
101     ~SysLogger();
102     
103     static SysLogger* GetInstance();
104 
105     bool InitLogger(const char* file_name, int min_level);
106     void WriteLog(int level, const char* exec_file, int exec_line, int tid, const char* format, ...);
107     void WriteLogNoLock(int level, const char* exec_file, int exec_line, int tid, const char* format, ...);
108 
109 private:
110     void set_log(int level, const char* exec_file, int exec_line, int tid, const char* format, va_list valst);
111     
112 public:
113     static SysLogger*   instance_;
114 
115 private:
116     int     min_level_;
117     char*   log_file_;
118     char*   log_buf_;
119     FILE*   log_fp_;
120     pthread_mutex_t*    mutex_;
121 };
122 
123 #endif

sys_logger.cpp

  1 #include "sys_logger.h"
  2 
  3 SysLogger* SysLogger::instance_ = NULL;
  4 
  5 SysLogger* SysLogger::GetInstance()
  6 {
  7     if (instance_ == NULL) {
  8         instance_ = new SysLogger();
  9     }
 10 
 11     return instance_;
 12 }
 13 
 14 SysLogger::SysLogger()
 15 {
 16     min_level_ = 0;
 17     log_fp_ = NULL;
 18     log_file_ = new char[MAX_FILENAME_LEN];
 19     memset(log_file_, 0, MAX_FILENAME_LEN);
 20     log_buf_ = new char[LOG_BUF_SIZE];
 21     mutex_ = new pthread_mutex_t;
 22     pthread_mutex_init(mutex_, NULL);
 23 }
 24 
 25 SysLogger::~SysLogger()
 26 {
 27     if (log_file_ != NULL) {
 28         delete[] log_file_;
 29         log_file_ = NULL;
 30     }
 31     
 32     if (log_buf_ != NULL) {
 33         delete[] log_buf_;
 34         log_buf_ = NULL;
 35     }
 36     
 37     if (log_fp_ != NULL) {
 38         fclose(log_fp_);
 39         log_fp_ = NULL;
 40     }
 41     
 42     pthread_mutex_destroy(mutex_);
 43 
 44     if (mutex_ != NULL) {
 45         delete mutex_;
 46     }
 47 }
 48 
 49 bool SysLogger::InitLogger(const char* file_name, int min_level)
 50 {
 51     strncpy(log_file_, file_name, MAX_FILENAME_LEN - 1);
 52     
 53     if (min_level >=0 && min_level <= 4) {
 54         min_level_ = min_level;
 55     }
 56     
 57     log_fp_ = fopen(log_file_, "a");
 58     
 59     if (log_fp_ == NULL) {
 60         return false;
 61     }
 62 
 63     return true;
 64 }
 65 
 66 void SysLogger::WriteLog(int level, const char* exec_file, int exec_line, int tid, const char* format, ...)
 67 {
 68     if (level < min_level_) {
 69         return;
 70     }
 71     
 72     pthread_mutex_lock(mutex_);
 73     va_list valst;
 74     va_start(valst, format);
 75     set_log(level, exec_file, exec_line, tid, format, valst);
 76     va_end(valst);
 77     
 78     fputs(log_buf_, log_fp_);
 79     fflush(log_fp_);
 80     
 81     // if (log_fp_ != NULL) {
 82         // fclose(log_fp_);
 83         // log_fp_ = NULL;
 84     // }
 85     
 86     pthread_mutex_unlock(mutex_);
 87 }
 88 
 89 // Used for mod exit
 90 void SysLogger::WriteLogNoLock(int level, const char* exec_file, int exec_line, int tid, const char* format, ...)
 91 {
 92     if (level < min_level_) {
 93         return;
 94     }
 95     
 96     va_list valst;
 97     va_start(valst, format);
 98     set_log(level, exec_file, exec_line, tid, format, valst);
 99     va_end(valst);
100     fputs(log_buf_, log_fp_);
101     fflush(log_fp_);
102     
103     // if (log_fp_ != NULL) {
104         // fclose(log_fp_);
105         // log_fp_ = NULL;
106     // }
107 }
108 
109 void SysLogger::set_log(int level, const char* exec_file, int exec_line, int tid, const char* format, va_list valst)
110 {
111     char exec_filename[MAX_FILENAME_LEN];
112     memset(exec_filename, 0, MAX_FILENAME_LEN);
113     const char* pch = strrchr(exec_file, /);
114     
115     if (pch == NULL) {
116         strncpy(exec_filename, exec_file, MAX_FILENAME_LEN - 1);
117     } else {
118         strncpy(exec_filename, pch + 1, MAX_FILENAME_LEN - 1);
119     }
120     
121     char levstr[16];
122     memset(levstr, 0, 16);
123     
124     switch (level) {
125         case LEVEL_SOCKET_DEBUG:
126         case LEVEL_DEBUG:
127             strcpy(levstr, "DEBUG");
128             break;
129         case LEVEL_INFO:
130             strcpy(levstr, "INFO");
131             break;
132         case LEVEL_WARNING:
133             strcpy(levstr, "WARN");
134             break;
135         case LEVEL_ERROR:
136             strcpy(levstr, "ERROR");
137             break;
138         default:
139             strcpy(levstr, "INFO");
140             break;
141     }
142     
143     if (log_fp_ == NULL) {
144         log_fp_ = fopen(log_file_, "a");
145     }
146     
147     memset(log_buf_, 0, LOG_BUF_SIZE);
148     struct timeval now = {0, 0};
149     gettimeofday(&now, NULL);
150     struct tm* sys_tm = localtime(&(now.tv_sec));
151     
152     int n = snprintf(log_buf_, 128, "\n%d-%02d-%02d %02d:%02d:%02d,%03d <%s> [%s:%d] [%d] ",
153                         sys_tm->tm_year + 1900, sys_tm->tm_mon + 1, sys_tm->tm_mday,
154                         sys_tm->tm_hour, sys_tm->tm_min, sys_tm->tm_sec, now.tv_usec / 1000, 
155                         levstr, exec_filename, exec_line, tid);
156     vsnprintf(log_buf_ + n, LOG_BUF_SIZE - n, format, valst);
157 }

 

简单的C/C++日志模块实现

标签:class   amp   ring   syslog   size   附加   实现   fda   log4c   

原文地址:http://www.cnblogs.com/lausaa/p/7594360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!