ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/logger.C
Revision: 1.2
Committed: Sat Jul 21 01:29:12 2007 UTC (16 years, 10 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.1: +1 -1 lines
Log Message:
- moved to new documentation system
- fixed small build error

File Contents

# Content
1 /*
2 * logger.C: Logging routines
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 */
7
8 static char const rcsid[] = "$Id";
9
10 #include "atheme.h"
11 #include <account/myuser.h>
12
13 static logfile_t *log_file;
14 int log_force;
15
16 static list_t log_files = { NULL, NULL, 0 };
17
18 /* private destructor function for logfile_t. */
19 static void
20 logfile_delete (void *vdata)
21 {
22 logfile_t *lf = static_cast<logfile_t *> (vdata);
23
24 logfile_unregister (lf);
25
26 fclose (static_cast<FILE *> (lf->log_file));
27 free (lf->log_path);
28 free (lf);
29 }
30
31 /*
32 * logfile_write(logfile_t *lf, const char *buf)
33 *
34 * Writes an I/O stream to a static file.
35 *
36 * Inputs:
37 * - logfile_t representing the I/O stream.
38 * - data to write to the file
39 *
40 * Outputs:
41 * - none
42 *
43 * Side Effects:
44 * - none
45 */
46 void
47 logfile_write (logfile_t *lf, const char *buf)
48 {
49 char datetime[64];
50 time_t t;
51 struct tm tm;
52
53 return_if_fail (lf != NULL);
54 return_if_fail (lf->log_file != NULL);
55 return_if_fail (buf != NULL);
56
57 time (&t);
58 tm = *localtime (&t);
59 strftime (datetime, sizeof (datetime) - 1, "[%d/%m/%Y %H:%M:%S]", &tm);
60
61 fprintf ((FILE *) lf->log_file, "%s %s\n", datetime, buf);
62 fflush ((FILE *) lf->log_file);
63 }
64
65 /*
66 * logfile_register(logfile_t *lf)
67 *
68 * Registers a log I/O stream.
69 *
70 * Inputs:
71 * - logfile_t representing the I/O stream.
72 *
73 * Outputs:
74 * - none
75 *
76 * Side Effects:
77 * - log_files is populated with the given object.
78 */
79 void
80 logfile_register (logfile_t *lf)
81 {
82 node_add (lf, &lf->node, &log_files);
83 }
84
85 /*
86 * logfile_unregister(logfile_t *lf)
87 *
88 * Registers a log I/O stream.
89 *
90 * Inputs:
91 * - logfile_t representing the I/O stream.
92 *
93 * Outputs:
94 * - none
95 *
96 * Side Effects:
97 * - log_files is populated with the given object.
98 */
99 void
100 logfile_unregister (logfile_t *lf)
101 {
102 node_del (&lf->node, &log_files);
103 }
104
105 /*
106 * logfile_new(const char *log_path, unsigned int log_mask)
107 *
108 * Logfile object factory.
109 *
110 * Inputs:
111 * - path to new logfile
112 * - bitmask of events to log
113 *
114 * Outputs:
115 * - a logfile_t object describing how this logfile should be used
116 *
117 * Side Effects:
118 * - log_files is populated with the newly created logfile_t.
119 */
120 logfile_t *
121 logfile_new (const char *path, unsigned int log_mask)
122 {
123 static time_t lastfail = 0;
124 logfile_t *lf = static_cast<logfile_t *> (scalloc (sizeof (logfile_t), 1));
125
126 object_init (asobject (lf), path, logfile_delete);
127 if ((lf->log_file = fopen (path, "a")) == NULL)
128 {
129 free (lf);
130
131 if (me.connected && lastfail + 3600 < NOW)
132 {
133 lastfail = NOW;
134 wallops (_("Could not open log file (%s), log entries will be missing!"), strerror (errno));
135 }
136
137 return NULL;
138 }
139 #ifdef FD_CLOEXEC
140 fcntl (fileno ((FILE *) lf->log_file), F_SETFD, FD_CLOEXEC);
141 #endif
142 lf->log_path = sstrdup (path);
143 lf->log_mask = log_mask;
144 lf->write_func = logfile_write;
145
146 logfile_register (lf);
147
148 return lf;
149 }
150
151 /*
152 * log_open(void)
153 *
154 * Initializes the logging subsystem.
155 *
156 * Inputs:
157 * - none
158 *
159 * Outputs:
160 * - none
161 *
162 * Side Effects:
163 * - the log_files list is populated with the master
164 * atheme.log reference.
165 */
166 void
167 log_open (void)
168 {
169 log_file = logfile_new (log_path, LG_ERROR | LG_INFO | LG_CMD_ADMIN);
170 }
171
172 /*
173 * log_shutdown(void)
174 *
175 * Shuts down the logging subsystem.
176 *
177 * Inputs:
178 * - none
179 *
180 * Outputs:
181 * - none
182 *
183 * Side Effects:
184 * - logfile_t objects in the log_files list are destroyed.
185 */
186 void
187 log_shutdown (void)
188 {
189 node_t *n, *tn;
190
191 LIST_FOREACH_SAFE (n, tn, log_files.head)
192 {
193 object_unref (n->data);
194 }
195 }
196
197 /*
198 * log_debug_enabled(void)
199 *
200 * Determines whether debug logging (LG_DEBUG and/or LG_RAWDATA) is enabled.
201 *
202 * Inputs:
203 * - none
204 *
205 * Outputs:
206 * - boolean
207 *
208 * Side Effects:
209 * - none
210 */
211 bool
212 log_debug_enabled (void)
213 {
214 node_t *n;
215 logfile_t *lf;
216
217 if (log_force)
218 return true;
219 LIST_FOREACH (n, log_files.head)
220 {
221 lf = static_cast<logfile_t *> (n->data);
222 if (lf->log_mask & (LG_DEBUG | LG_RAWDATA))
223 return true;
224 }
225 return false;
226 }
227
228 /*
229 * log_master_set_mask(unsigned int mask)
230 *
231 * Sets the logging mask for the main log file.
232 *
233 * Inputs:
234 * - mask
235 *
236 * Outputs:
237 * - none
238 *
239 * Side Effects:
240 * - logging mask updated
241 */
242 void
243 log_master_set_mask (unsigned int mask)
244 {
245 /* couldn't be opened etc */
246 if (log_file == NULL)
247 return;
248 log_file->log_mask = mask;
249 }
250
251 /*
252 * slog(unsigned int level, const char *fmt, ...)
253 *
254 * Handles the basic logging of log messages to the log files defined
255 * in the configuration file. All I/O is handled here, and no longer
256 * in the various sourceinfo_t log transforms.
257 *
258 * Inputs:
259 * - a bitmask of the various log categories this event qualifies to
260 * - a printf-style format string
261 * - (optional) additional arguments to be used with that format string
262 *
263 * Outputs:
264 * - none
265 *
266 * Side Effects:
267 * - logfiles are updated depending on how they are configured.
268 */
269 void
270 slog (unsigned int level, const char *fmt, ...)
271 {
272 va_list args;
273 char buf[BUFSIZE];
274 node_t *n;
275 char datetime[64];
276 time_t t;
277 struct tm tm;
278
279 va_start (args, fmt);
280 vsnprintf (buf, BUFSIZE, fmt, args);
281 va_end (args);
282
283 time (&t);
284 tm = *localtime (&t);
285 strftime (datetime, sizeof (datetime) - 1, "[%d/%m/%Y %H:%M:%S]", &tm);
286
287 LIST_FOREACH (n, log_files.head)
288 {
289 logfile_t *lf = (logfile_t *) n->data;
290
291 if ((lf != log_file || !log_force) && !(level & lf->log_mask))
292 continue;
293
294 return_if_fail (lf->write_func != NULL);
295
296 lf->write_func (lf, buf);
297 }
298
299 /*
300 * if the event is in the default loglevel, and we are starting, then
301 * display it in the controlling terminal.
302 */
303 if (((runflags & (RF_LIVE | RF_STARTING)) && (log_file != NULL ? log_file->log_mask : LG_ERROR | LG_INFO) & level) || ((runflags & RF_LIVE) && log_force))
304 fprintf (stderr, "%s %s\n", datetime, buf);
305 }
306
307 /*
308 * logcommand(sourceinfo_t *si, int level, const char *fmt, ...)
309 *
310 * Logs usage of a command from a user or other source (RPC call) as
311 * described by sourceinfo_t.
312 *
313 * Inputs:
314 * - sourceinfo_t object which describes the source of the command call
315 * - bitmask of log categories to log the command use to.
316 * - printf-style format string
317 * - (optional) additional parameters
318 *
319 * Outputs:
320 * - none
321 *
322 * Side Effects:
323 * - qualifying logfile_t objects in log_files are updated.
324 */
325 void
326 logcommand (sourceinfo_t *si, int level, const char *fmt, ...)
327 {
328 va_list args;
329 char lbuf[BUFSIZE];
330
331 va_start (args, fmt);
332 vsnprintf (lbuf, BUFSIZE, fmt, args);
333 va_end (args);
334 if (si->su != NULL)
335 logcommand_user (si->service, si->su, level, "%s", lbuf);
336 else
337 logcommand_external (si->service, si->v != NULL ? si->v->description : "unknown", si->connection, si->sourcedesc, si->smu, level, "%s", lbuf);
338 }
339
340 /*
341 * logcommand_user(service_t *svs, user_t *source, int level, const char *fmt, ...)
342 *
343 * Logs usage of a command from a user as described by sourceinfo_t.
344 *
345 * Inputs:
346 * - service_t object which describes the service the command is attached to
347 * - user_t object which describes the source of the command call
348 * - bitmask of log categories to log the command use to.
349 * - printf-style format string
350 * - (optional) additional parameters
351 *
352 * Outputs:
353 * - none
354 *
355 * Side Effects:
356 * - qualifying logfile_t objects in log_files are updated.
357 */
358 void
359 logcommand_user (service_t *svs, user_t *source, int level, const char *fmt, ...)
360 {
361 va_list args;
362 char lbuf[BUFSIZE];
363
364 va_start (args, fmt);
365 vsnprintf (lbuf, BUFSIZE, fmt, args);
366 va_end (args);
367
368 slog (level, "%s %s:%s!%s@%s[%s] %s", svs != NULL ? svs->name : me.name, source->myuser != NULL ? source->myuser->name : "", source->nick, source->user, source->vhost, source->ip[0] != '\0' ? source->ip : source->host, lbuf);
369 }
370
371 /*
372 * logcommand_external(service_t *svs, const char *type, connection_t *source,
373 * const char *sourcedesc, myuser_t *login, int level, const char *fmt, ...)
374 *
375 * Logs usage of a command from an RPC call as described by sourceinfo_t.
376 *
377 * Inputs:
378 * - service_t object which describes the service the command is attached to
379 * - string which describes the type of RPC call
380 * - connection_t which describes the socket source of the RPC call
381 * - string which describes the socket source of the RPC call
382 * - myuser_t which describes the services account used for the RPC call
383 * - bitmask of log categories to log the command use to.
384 * - printf-style format string
385 * - (optional) additional parameters
386 *
387 * Outputs:
388 * - none
389 *
390 * Side Effects:
391 * - qualifying logfile_t objects in log_files are updated.
392 */
393 void
394 logcommand_external (service_t *svs, const char *type, connection_t *source, const char *sourcedesc, myuser_t *login, int level, const char *fmt, ...)
395 {
396 va_list args;
397 char lbuf[BUFSIZE];
398
399 va_start (args, fmt);
400 vsnprintf (lbuf, BUFSIZE, fmt, args);
401 va_end (args);
402
403 slog (level, "%s %s:%s(%s)[%s] %s", svs != NULL ? svs->name : me.name, login != NULL ? login->name : "", type, source != NULL ? source->hbuf : "<noconn>", sourcedesc != NULL ? sourcedesc : "<unknown>", lbuf);
404 }