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 |
179 |
185 |
180 writev(log_file_fd, io, 2); /* TODO: aio? */ |
186 writev(log_file_fd, io, 2); /* TODO: aio? */ |
181 if(!main_is_daemon()) { |
187 if(!main_is_daemon()) { |
182 writev(STDOUT_FILENO, io, 2); |
188 writev(STDOUT_FILENO, io, 2); |
183 } |
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); |
|
204 } |
184 } |
205 } |
185 |
206 |
186 sstr_t log_get_prefix(int level) { |
207 sstr_t log_get_prefix(int level) { |
187 time_t t = time(NULL); |
208 time_t t = time(NULL); |
188 |
209 |
212 } |
233 } |
213 |
234 |
214 return d; |
235 return d; |
215 } |
236 } |
216 |
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 *dup) { |
|
246 pthread_mutex_lock(&mutex); |
|
247 UcxList *elm = log_dup_list; |
|
248 while(elm) { |
|
249 if(elm->data = dup) { |
|
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 |
217 |
259 |
218 /* |
260 /* |
219 * log api functions |
261 * log api functions |
220 */ |
262 */ |
221 |
263 |