ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/logger.C
Revision: 1.5
Committed: Thu Aug 30 19:56:25 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.4: +2 -1 lines
Log Message:
- put faultcodes into their own namespace
- removed old files
- limited header garbage in atheme.h
- macros to inline bools for connection_t::is_*
- put some connection_t functions into the connection_t class

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