src/server/daemon/log.c

changeset 28
f387669912e8
child 32
ebba53de8b18
equal deleted inserted replaced
27:05b7576dca2b 28:f387669912e8
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2011 Olaf Wintermann. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include <aio.h>
34 #include <time.h>
35
36 #include "log.h"
37 #include "../util/strbuf.h"
38
39 int is_initialized = 0;
40
41 int log_file_fd;
42 int log_level = 0;
43
44 /*
45 * if the log file is uninitialized, output is written to the ui_buffer
46 */
47 sbuf_t *ui_buffer = NULL;
48
49 char *log_date_month[] = {
50 "Jan",
51 "Feb",
52 "Mar",
53 "Apr",
54 "May",
55 "Jun",
56 "Jul",
57 "Aug",
58 "Sep",
59 "Oct",
60 "Nov",
61 "Dec"
62 };
63
64 char *log_levels[] = {
65 "error",
66 "warning",
67 "info"
68 };
69
70 int init_log_file(LogConfig *cfg) {
71 if(is_initialized) {
72 return 0;
73 }
74
75 /* open the log file */
76 mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
77 log_file_fd = open(cfg->file, O_WRONLY | O_CREAT | O_APPEND, mode);
78 if(log_file_fd == -1) {
79 return -1;
80 }
81
82 if(!strcmp(cfg->level, "ERROR")) {
83 log_level = LOG_LEVEL_ERROR;
84 } else if(!strcmp(cfg->level, "WARNING")) {
85 log_level = LOG_LEVEL_WARNING;
86 } else if(!strcmp(cfg->level, "INFO")) {
87 log_level = LOG_LEVEL_INFO;
88 }
89
90 if(cfg->log_stdout) {
91 // TODO
92 }
93 if(cfg->log_stderr) {
94 // TODO
95 }
96
97
98 is_initialized = 1;
99
100 /* if ui_buffer is not NULL, write it to the log file */
101 if(ui_buffer) {
102 size_t len = ui_buffer->length;
103 size_t r;
104 while(len > 0) {
105 r = write(log_file_fd, ui_buffer->ptr, ui_buffer->length);
106 len -= r;
107 }
108
109 sbuf_free(ui_buffer);
110 }
111
112 return 0;
113 }
114
115 void log_uninitialized_writeln(char *str, size_t len) {
116 if(ui_buffer == NULL) {
117 ui_buffer = sbuf_new(1024);
118 if(ui_buffer == NULL) {
119 return; /* TODO: critical error, exit */
120 }
121 }
122
123 sstr_t s;
124 s.ptr = str;
125 s.length = len;
126
127 sbuf_append(ui_buffer, s);
128 sbuf_put(ui_buffer, '\n');
129 }
130
131 void log_file_writeln(char *str, size_t len) {
132 if(!is_initialized) {
133 log_uninitialized_writeln(str, len);
134 }
135
136 struct iovec io[] = {
137 { str, len },
138 { "\n", 1}
139 };
140
141 writev(log_file_fd, io, 2); /* TODO: aio */
142 }
143
144 sstr_t log_get_prefix(int level) {
145 time_t t = time(NULL);
146
147 sstr_t d;
148 d.ptr = NULL;
149 d.length = 0;
150
151 struct tm date;
152 localtime_r(&t, &date);
153
154 char *buf = malloc(64);
155 int len = snprintf(
156 buf,
157 64,
158 "[%02d/%s/%d:%02d:%02d:%02d] %s : ",
159 date.tm_mday,
160 log_date_month[date.tm_mon],
161 1900 + date.tm_year,
162 date.tm_hour,
163 date.tm_min,
164 date.tm_sec,
165 log_levels[level]);
166
167 if(len > 0) {
168 d.ptr = buf;
169 d.length = len;
170 }
171
172 return d;
173 }
174
175
176 /*
177 * log api functions
178 */
179
180 int log_ereport(int degree, const char *format, ...) {
181 if(degree > log_level) {
182 return 0;
183 }
184
185 sstr_t lmsg;
186 lmsg.ptr = NULL;
187 va_list ap;
188 va_start(ap, format);
189
190 /* create log message prefix */
191 sstr_t lpre = log_get_prefix(degree);
192
193 /* format message */
194 int len = vasprintf(&lmsg.ptr, format, ap);
195 lmsg.length = len;
196
197 /* create message string */
198 sstr_t message;
199 message.length = lpre.length + len;
200 message.ptr = malloc(message.length + 1);
201
202 message = sstrncat(2, message, lpre, lmsg);
203
204 /* write message to the log file */
205 log_file_writeln(message.ptr, message.length);
206
207 /* cleanup */
208 free(lmsg.ptr);
209 free(message.ptr);
210
211 return 0;
212 }

mercurial