诸如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 }
来源:https://www.cnblogs.com/lausaa/p/7594360.html