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

# Content
1 /**
2 * logger.C: Logging routines
3 * Rights to this code are documented in doc/pod/license.pod.
4 *
5 * Copyright © 2007 Pippijn van Steenhoven / The Ermyth Team (http://ermyth.schmorp.de)
6 * Copyright © 2005-2007 Atheme Project (http://www.atheme.org)
7 */
8
9 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
13 #include "atheme.h"
14 #include "connection.h"
15 #include <account/myuser.h>
16
17 static logfile_t *log_file;
18 int log_force;
19
20 typedef indexing_vector<logfile_t> logfile_vector;
21 static logfile_vector log_files;
22
23 /* private destructor function for logfile_t. */
24 void
25 logfile_t::_destroy ()
26 {
27 this->leave ();
28
29 fclose (static_cast<FILE *> (log_file));
30 sfree (log_path);
31 delete this;
32 }
33
34 /*
35 * logfile_write(logfile_t *lf, char const * const buf)
36 *
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 logfile_t::write (char const * const buf)
51 {
52 char datetime[64];
53 time_t t;
54 struct tm tm;
55
56 return_if_fail (this != NULL);
57 return_if_fail (log_file != NULL);
58 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 fprintf ((FILE *) log_file, "%s %s\n", datetime, buf);
65 fflush ((FILE *) log_file);
66 }
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 logfile_t::enter ()
84 {
85 log_files.insert (this);
86 }
87
88 /*
89 * logfile_unregister(logfile_t *lf)
90 *
91 * Unregisters a log I/O stream.
92 *
93 * Inputs:
94 * - logfile_t representing the I/O stream.
95 *
96 * Outputs:
97 * - none
98 *
99 * Side Effects:
100 * - the given object is removed from log_files, but remains valid.
101 */
102 void
103 logfile_t::leave ()
104 {
105 log_files.erase (this);
106 }
107
108 /*
109 * logfile_new(char const * const log_path, unsigned int log_mask)
110 *
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 logfile_t::create (char const * const path, unsigned int log_mask)
125 {
126 static time_t lastfail = 0;
127 logfile_t *lf = new logfile_t;
128
129 if ((lf->log_file = fopen (path, "a")) == NULL)
130 {
131 delete lf;
132
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 lf->enter ();
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_t::create (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 while (!log_files.empty ())
191 log_files.back ()->refcnt_dec ();
192 }
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 foreach (logfile_t *lf, log_files)
214 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 * slog(unsigned int level, char const * const fmt, ...)
244 *
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 slog (unsigned int level, char const * const fmt, ...)
262 {
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 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 /*
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 * logcommand(sourceinfo_t *si, int level, char const * const fmt, ...)
295 *
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 logcommand (sourceinfo_t *si, int level, char const * const fmt, ...)
313 {
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 * logcommand_user(service_t *svs, user_t *source, int level, char const * const fmt, ...)
328 *
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 logcommand_user (service_t *svs, user_t *source, int level, char const * const fmt, ...)
346 {
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 * 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 *
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 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 {
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 }