forked from 0xmalloc/c-log
-
Notifications
You must be signed in to change notification settings - Fork 0
/
log.c
171 lines (152 loc) · 4.1 KB
/
log.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include "log.h"
#include <sys/file.h>
#include <stdarg.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
Log_Writer WARN_W;
Log_Writer INFO_W;
__thread char Log_Writer::m_buffer[_LOG_BUFFSIZE];
bool log_init(LogLevel l, const char* p_modulename, const char* p_logdir)
{
//如果路径存在文件夹,则判断是否存在
if (access (p_logdir, 0) == -1)
{
if (mkdir (p_logdir, S_IREAD | S_IWRITE ) < 0)
fprintf(stderr, "create folder failed\n");
}
char _location_str[_LOG_PATH_LEN];
snprintf(_location_str, _LOG_PATH_LEN, "%s/%s.access", p_logdir, p_modulename);
INFO_W.loginit(l, _location_str);
snprintf(_location_str, _LOG_PATH_LEN, "%s/%s.error", p_logdir, p_modulename);
//warning级别以上日志去WARN_W 去向由宏决定的 请见macro_define.h
if(l > LL_WARNING)
WARN_W.loginit(l, _location_str);
else
WARN_W.loginit(LL_WARNING, _location_str);
return true;
}
const char* Log_Writer::logLevelToString(LogLevel l) {
switch ( l ) {
case LL_DEBUG:
return "DEBUG";
case LL_TRACE:
return "TRACE";
case LL_NOTICE:
return "NOTICE";
case LL_WARNING:
return "WARN" ;
case LL_ERROR:
return "ERROR";
default:
return "UNKNOWN";
}
}
bool Log_Writer::checklevel(LogLevel l)
{
if(l >= m_system_level)
return true;
else
return false;
}
bool Log_Writer::loginit(LogLevel l, const char *filelocation, bool append, bool issync)
{
MACRO_RET(NULL != fp, false);
m_system_level = l;
m_isappend = append;
m_issync = issync;
if(strlen(filelocation) >= (sizeof(m_filelocation) -1))
{
fprintf(stderr, "the path of log file is too long:%d limit:%d\n", strlen(filelocation), sizeof(m_filelocation) -1);
exit(0);
}
//本地存储filelocation 以防止在栈上的非法调用调用
strncpy(m_filelocation, filelocation, sizeof(m_filelocation));
m_filelocation[sizeof(m_filelocation) -1] = '\0';
if('\0' == m_filelocation[0])
{
fp = stdout;
fprintf(stderr, "now all the running-information are going to put to stderr\n");
return true;
}
fp = fopen(m_filelocation, append ? "a":"w");
if(fp == NULL)
{
fprintf(stderr, "cannot open log file,file location is %s\n", m_filelocation);
exit(0);
}
//setvbuf (fp, io_cached_buf, _IOLBF, sizeof(io_cached_buf)); //buf set _IONBF _IOLBF _IOFBF
setvbuf (fp, (char *)NULL, _IOLBF, 0);
fprintf(stderr, "now all the running-information are going to the file %s\n", m_filelocation);
return true;
}
int Log_Writer::premakestr(char* m_buffer, LogLevel l)
{
time_t now;
now = time(&now);;
struct tm vtm;
localtime_r(&now, &vtm);
return snprintf(m_buffer, _LOG_BUFFSIZE, "%s: %02d-%02d %02d:%02d:%02d ", logLevelToString(l),
vtm.tm_mon + 1, vtm.tm_mday, vtm.tm_hour, vtm.tm_min, vtm.tm_sec);
}
bool Log_Writer::log(LogLevel l, char* logformat,...)
{
MACRO_RET(!checklevel(l), false);
int _size;
int prestrlen = 0;
char * star = m_buffer;
prestrlen = premakestr(star, l);
star += prestrlen;
va_list args;
va_start(args, logformat);
_size = vsnprintf(star, _LOG_BUFFSIZE - prestrlen, logformat, args);
va_end(args);
if(NULL == fp)
fprintf(stderr, "%s", m_buffer);
else
_write(m_buffer, prestrlen + _size);
return true;
}
bool Log_Writer::_write(char *_pbuffer, int len)
{
if(0 != access(m_filelocation, W_OK))
{
pthread_mutex_lock(&m_mutex);
//锁内校验 access 看是否在等待锁过程中被其他线程loginit了 避免多线程多次close 和init
if(0 != access(m_filelocation, W_OK))
{
logclose();
loginit(m_system_level, m_filelocation, m_isappend, m_issync);
}
pthread_mutex_unlock(&m_mutex);
}
if(1 == fwrite(_pbuffer, len, 1, fp)) //only write 1 item
{
if(m_issync)
fflush(fp);
*_pbuffer='\0';
}
else
{
int x = errno;
fprintf(stderr, "Failed to write to logfile. errno:%s message:%s", strerror(x), _pbuffer);
return false;
}
return true;
}
LogLevel Log_Writer::get_level()
{
return m_system_level;
}
bool Log_Writer::logclose()
{
if(fp == NULL)
return false;
fflush(fp);
fclose(fp);
fp = NULL;
return true;
}