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

# User Rev Content
1 pippijn 1.1 /*
2     * logger.C: Logging routines
3 pippijn 1.2 * Rights to this code are documented in doc/pod/license.pod.
4 pippijn 1.1 *
5 pippijn 1.4 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
6 pippijn 1.1 */
7    
8 pippijn 1.5 static char const rcsid[] = "$Id: logger.C,v 1.4 2007-08-28 17:08:12 pippijn Exp $";
9 pippijn 1.1
10     #include "atheme.h"
11 pippijn 1.5 #include "connection.h"
12 pippijn 1.1 #include <account/myuser.h>
13    
14     static logfile_t *log_file;
15     int log_force;
16    
17 pippijn 1.4 static list_t log_files;
18 pippijn 1.1
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 pippijn 1.4 sfree (lf->log_path);
29     delete lf;
30 pippijn 1.1 }
31    
32     /*
33 pippijn 1.4 * logfile_write(logfile_t *lf, char const * const buf)
34 pippijn 1.1 *
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 pippijn 1.4 logfile_write (logfile_t *lf, char const * const buf)
49 pippijn 1.1 {
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 pippijn 1.4 * Unregisters a log I/O stream.
90 pippijn 1.1 *
91     * Inputs:
92     * - logfile_t representing the I/O stream.
93     *
94     * Outputs:
95     * - none
96     *
97     * Side Effects:
98 pippijn 1.4 * - the given object is removed from log_files, but remains valid.
99 pippijn 1.1 */
100     void
101     logfile_unregister (logfile_t *lf)
102     {
103     node_del (&lf->node, &log_files);
104     }
105    
106     /*
107 pippijn 1.4 * logfile_new(char const * const log_path, unsigned int log_mask)
108 pippijn 1.1 *
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 pippijn 1.4 logfile_new (char const * const path, unsigned int log_mask)
123 pippijn 1.1 {
124     static time_t lastfail = 0;
125 pippijn 1.4 logfile_t *lf = new logfile_t;
126 pippijn 1.1
127     object_init (asobject (lf), path, logfile_delete);
128     if ((lf->log_file = fopen (path, "a")) == NULL)
129     {
130 pippijn 1.4 delete lf;
131 pippijn 1.1
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 pippijn 1.4 * slog(unsigned int level, char const * const fmt, ...)
254 pippijn 1.1 *
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 pippijn 1.4 slog (unsigned int level, char const * const fmt, ...)
272 pippijn 1.1 {
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 pippijn 1.4 * logcommand(sourceinfo_t *si, int level, char const * const fmt, ...)
310 pippijn 1.1 *
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 pippijn 1.4 logcommand (sourceinfo_t *si, int level, char const * const fmt, ...)
328 pippijn 1.1 {
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 pippijn 1.4 * logcommand_user(service_t *svs, user_t *source, int level, char const * const fmt, ...)
343 pippijn 1.1 *
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 pippijn 1.4 logcommand_user (service_t *svs, user_t *source, int level, char const * const fmt, ...)
361 pippijn 1.1 {
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 pippijn 1.4 * 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 pippijn 1.1 *
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 pippijn 1.4 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 pippijn 1.1 {
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     }