34 #include <stdlib.h> |
34 #include <stdlib.h> |
35 #include <string.h> |
35 #include <string.h> |
36 #include <unistd.h> |
36 #include <unistd.h> |
37 #include <aio.h> |
37 #include <aio.h> |
38 #include <time.h> |
38 #include <time.h> |
|
39 #include <pthread.h> |
39 |
40 |
40 #include "log.h" |
41 #include "log.h" |
41 #include "../util/strbuf.h" |
42 #include "../util/strbuf.h" |
42 #include "../util/io.h" |
43 #include "../util/io.h" |
43 #include "../util/atomic.h" |
44 #include "../util/atomic.h" |
44 |
45 |
45 #include <ucx/map.h> |
46 #include <ucx/map.h> |
|
47 #include <ucx/list.h> |
46 |
48 |
47 static int is_initialized = 0; |
49 static int is_initialized = 0; |
48 |
50 |
49 static int log_file_fd; |
51 static int log_file_fd; |
50 static int log_level = 0; |
52 static int log_level = 0; |
|
53 |
|
54 static uint32_t log_dup_count = 0; |
|
55 static UcxList *log_dup_list = NULL; |
|
56 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
51 |
57 |
52 WSBool main_is_daemon(void); |
58 WSBool main_is_daemon(void); |
53 |
59 |
54 /* |
60 /* |
55 * if the log file is uninitialized, output is written to the ui_buffer |
61 * if the log file is uninitialized, output is written to the ui_buffer |
112 if(!strcmp(cfg->level, "ERROR")) { |
120 if(!strcmp(cfg->level, "ERROR")) { |
113 can_log[LOG_WARN] = 0; |
121 can_log[LOG_WARN] = 0; |
114 can_log[LOG_INFORM] = 0; |
122 can_log[LOG_INFORM] = 0; |
115 } else if(!strcmp(cfg->level, "WARNING")) { |
123 } else if(!strcmp(cfg->level, "WARNING")) { |
116 can_log[LOG_INFORM] = 0; |
124 can_log[LOG_INFORM] = 0; |
117 } else if(!strcmp(cfg->level, "INFO")) { |
|
118 |
|
119 } else if(!strcmp(cfg->level, "VERBOSE")) { |
125 } else if(!strcmp(cfg->level, "VERBOSE")) { |
120 can_log[LOG_VERBOSE] = 1; |
126 can_log[LOG_VERBOSE] = 1; |
|
127 } else if(!strcmp(cfg->level, "DEBUG")) { |
|
128 can_log[LOG_VERBOSE] = 1; |
|
129 can_log[LOG_DEBUG] = 1; |
121 } |
130 } |
122 |
131 |
123 if(cfg->log_stdout) { |
132 if(cfg->log_stdout) { |
124 // TODO |
133 // TODO |
125 } |
134 } |
175 }; |
184 }; |
176 |
185 |
177 writev(log_file_fd, io, 2); /* TODO: aio? */ |
186 writev(log_file_fd, io, 2); /* TODO: aio? */ |
178 if(!main_is_daemon()) { |
187 if(!main_is_daemon()) { |
179 writev(STDOUT_FILENO, io, 2); |
188 writev(STDOUT_FILENO, io, 2); |
|
189 } |
|
190 |
|
191 if(log_dup_count > 0) { |
|
192 char *msg = malloc(len + 1); |
|
193 memcpy(msg, str, len); |
|
194 msg[len] = '\n'; |
|
195 |
|
196 pthread_mutex_lock(&mutex); |
|
197 UCX_FOREACH(elm, log_dup_list) { |
|
198 LogDup *dup = elm->data; |
|
199 dup->write(dup->cookie, msg, len + 1); |
|
200 } |
|
201 pthread_mutex_unlock(&mutex); |
|
202 |
|
203 free(msg); |
180 } |
204 } |
181 } |
205 } |
182 |
206 |
183 sstr_t log_get_prefix(int level) { |
207 sstr_t log_get_prefix(int level) { |
184 time_t t = time(NULL); |
208 time_t t = time(NULL); |
209 } |
233 } |
210 |
234 |
211 return d; |
235 return d; |
212 } |
236 } |
213 |
237 |
|
238 void log_add_logdup(LogDup *dup) { |
|
239 pthread_mutex_lock(&mutex); |
|
240 log_dup_list = ucx_list_append(log_dup_list, dup); |
|
241 ws_atomic_inc32(&log_dup_count); |
|
242 pthread_mutex_unlock(&mutex); |
|
243 } |
|
244 |
|
245 void log_remove_logdup(LogDup *ldup) { |
|
246 pthread_mutex_lock(&mutex); |
|
247 UcxList *elm = log_dup_list; |
|
248 while(elm) { |
|
249 if(elm->data == ldup) { |
|
250 log_dup_list = ucx_list_remove(log_dup_list, elm); |
|
251 ws_atomic_dec32(&log_dup_count); |
|
252 break; |
|
253 } |
|
254 elm = elm->next; |
|
255 } |
|
256 pthread_mutex_unlock(&mutex); |
|
257 } |
|
258 |
214 |
259 |
215 /* |
260 /* |
216 * log api functions |
261 * log api functions |
217 */ |
262 */ |
218 |
263 |