ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/src/logger.C
Revision: 1.6
Committed: Sun Sep 9 20:05:52 2007 UTC (16 years, 8 months ago) by pippijn
Content type: text/plain
Branch: MAIN
Changes since 1.5: +36 -51 lines
Log Message:
- changed configurations to the c++ stdlib
- more #defines to enum
- removed getopt.h and link.h from the system as they were unused
- reworked logstreams
- added an itoa with old syntax
- made klines objects
- moved some global variables into appropriate classes
- fixed boost.foreach's compiler workaround #if's
- allow other files to add exceptions with ADD_EXCEPTION
- changed mynick_t to c++ object
- moved servers.h out of atheme.h
- corrected PING from inspircd 1.2

File Contents

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