诸如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 }
时间: 2024-10-11 00:22:05