ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/log.c
(Generate patch)

Comparing:
ircd-hybrid/src/s_log.c (file contents), Revision 1028 by michael, Sun Nov 8 13:03:38 2009 UTC vs.
ircd-hybrid-8/src/log.c (file contents), Revision 1324 by michael, Fri Mar 30 21:40:38 2012 UTC

# Line 1 | Line 1
1   /*
2   *  ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 < *  s_log.c: Logger functions.
3 > *  log.c: Logger functions.
4   *
5   *  Copyright (C) 2002 by the past and present ircd coders, and others.
6   *
# Line 24 | Line 24
24  
25   #include "stdinc.h"
26  
27 < #ifdef USE_SYSLOG
28 < # ifdef HAVE_SYS_SYSLOG_H
29 < #  include <sys/syslog.h>
30 < # else
31 < #  ifdef HAVE_SYSLOG_H
32 < #   include <syslog.h>
33 < #  endif
34 < # endif
35 < #endif
36 <
37 < #include "client.h"     /* Needed for struct Client */
38 < #include "common.h"
39 < #include "s_log.h"
27 > #include "log.h"
28   #include "fileio.h"
29   #include "irc_string.h"
42 – #include "sprintf_irc.h"
30   #include "ircd.h"
31 + #include "conf.h"
32 + #include "send.h"
33   #include "s_misc.h"
45 – #include "event.h"      /* Needed for EVH etc. */
46 – #include "s_conf.h"
47 – #include "memory.h"
34  
49 – /* some older syslogs would overflow at 2024 */
50 – #define LOG_BUFSIZE 2000
35  
36 < static FBFILE *logFile;
37 < static int logLevel = INIT_LOG_LEVEL;
36 > static struct {
37 >  char path[PATH_MAX + 1];
38 >  size_t size;
39 >  FBFILE *file;
40 > } log_type_table[LOG_TYPE_LAST];
41  
55 – #ifndef SYSLOG_USERS
56 – static EVH user_log_resync;
57 – static FBFILE *user_log_fb = NULL;
58 – #endif
42  
43 <
44 < #ifdef USE_SYSLOG
62 < static const int sysLogLevel[] =
43 > int
44 > log_add_file(enum log_type type, size_t size, const char *path)
45   {
46 <  LOG_CRIT,
47 <  LOG_ERR,
66 <  LOG_WARNING,
67 <  LOG_NOTICE,
68 <  LOG_INFO,
69 <  LOG_INFO,
70 <  LOG_INFO
71 < };
72 < #endif
46 >  if (log_type_table[type].file)
47 >    fbclose(log_type_table[type].file);
48  
49 < static const char *logLevelToString[] =
50 < {
76 <  "L_CRIT",
77 <  "L_ERROR",
78 <  "L_WARN",
79 <  "L_NOTICE",
80 <  "L_TRACE",
81 <  "L_INFO",
82 <  "L_DEBUG"
83 < };
49 >  strlcpy(log_type_table[type].path, path, sizeof(log_type_table[type].path));
50 >  log_type_table[type].size = size;
51  
52 < /*
53 < * open_log - open ircd logging file
54 < * returns true (1) if successful, false (0) otherwise
55 < */
56 < static int
90 < open_log(const char *filename)
52 >  return (log_type_table[type].file = fbopen(path, "a")) != NULL;
53 > }
54 >
55 > void
56 > log_close_all(void)
57   {
58 <  logFile = fbopen(filename, "a");
58 >  unsigned int type = 0;
59  
60 <  if (logFile == NULL)
60 >  while (++type < LOG_TYPE_LAST)
61    {
62 < #ifdef USE_SYSLOG
63 <    syslog(LOG_ERR, "Unable to open log file: %s: %s",
64 <           filename, strerror(errno));
65 < #endif
66 <    return (0);
62 >    if (log_type_table[type].file == NULL)
63 >      continue;
64 >
65 >    fbclose(log_type_table[type].file);
66 >    log_type_table[type].file = NULL;
67    }
68 + }
69  
70 <  return (1);
70 > static int
71 > log_exceed_size(unsigned int type)
72 > {
73 >  struct stat sb;
74 >
75 >  if (!log_type_table[type].size)
76 >    return 0;
77 >
78 >  if (stat(log_type_table[type].path, &sb) < 0)
79 >    return -1;
80 >
81 >  return (size_t)sb.st_size > log_type_table[type].size;
82   }
83  
84 +
85   static void
86 < write_log(const char *message)
86 > write_log(enum log_type type, const char *message)
87   {
88    char buf[LOG_BUFSIZE];
89    size_t nbytes = 0;
90 +  struct tm *lt = localtime(&CurrentTime);
91  
92 <  if (logFile == NULL)
93 <    return;
114 <
115 <  nbytes = snprintf(buf, sizeof(buf), "[%s] %s\n",
116 <                    smalldate(CurrentTime), message);
92 >  nbytes = strftime(buf, sizeof(buf), "[%FT%H:%M:%S%z] ", lt);
93 >  nbytes += snprintf(buf+nbytes, sizeof(buf)-nbytes, "%s\n", message);
94  
95 <  fbputs(buf, logFile, nbytes);
95 >  fbputs(buf, log_type_table[type].file, nbytes);
96   }
97    
98   void
99 < ilog(const int priority, const char *fmt, ...)
99 > ilog(enum log_type type, const char *fmt, ...)
100   {
101    char buf[LOG_BUFSIZE];
102    va_list args;
103  
104 <  assert(priority > -1);
128 <
129 <  if (fmt == NULL)
130 <    return;
131 <
132 <  if (priority > logLevel)
104 >  if (log_type_table[type].file == NULL)
105      return;
106  
107    va_start(args, fmt);
108 <  vsprintf(buf, fmt, args);
108 >  vsnprintf(buf, sizeof(buf), fmt, args);
109    va_end(args);
110  
139 – #ifdef USE_SYSLOG  
140 –  if (priority <= L_DEBUG)
141 –    syslog(sysLogLevel[priority], "%s", buf);
142 – #endif
111    if (ConfigLoggingEntry.use_logging)
144 –    write_log(buf);
145 – }
146 –  
147 – void
148 – init_log(const char *filename)
149 – {
150 –  open_log(filename);
151 – #ifdef USE_SYSLOG
152 –  openlog("ircd", LOG_PID | LOG_NDELAY, LOG_FACILITY);
153 – #endif
154 – #ifndef SYSLOG_USERS
155 –  eventAddIsh("user_log_resync", user_log_resync, NULL, 60);
156 – #endif
157 – }
158 –
159 – void
160 – reopen_log(const char *filename)
161 – {
162 –  if (logFile != NULL)
163 –    fbclose(logFile);
164 –  open_log(filename);
165 – }
166 –
167 – void
168 – set_log_level(const int level)
169 – {
170 –  if (L_ERROR < level && level <= L_DEBUG)
171 –    logLevel = level;
172 – }
173 –
174 – int
175 – get_log_level(void)
176 – {
177 –  return(logLevel);
178 – }
179 –
180 – const char *
181 – get_log_level_as_string(int level)
182 – {
183 –  if (level > L_DEBUG)
184 –    level = L_DEBUG;
185 –  else if (level < L_ERROR)
186 –    level = L_ERROR;
187 –
188 –  return(logLevelToString[level]);
189 – }
190 –
191 – /* log_user_exit()
192 – *
193 – * inputs       - pointer to connecting client
194 – * output       - NONE
195 – * side effects - Current exiting client is logged to
196 – *                either SYSLOG or to file.
197 – */
198 – void
199 – log_user_exit(struct Client *source_p)
200 – {
201 –  time_t on_for = CurrentTime - source_p->firsttime;
202 – #ifdef SYSLOG_USERS
203 –  if (IsClient(source_p))
204 –  {
205 –    ilog(L_INFO, "%s (%3u:%02u:%02u): %s!%s@%s %llu/%llu",
206 –         myctime(source_p->firsttime), (unsigned int)(on_for / 3600),
207 –         (unsigned int)((on_for % 3600)/60), (unsigned int)(on_for % 60),
208 –         source_p->name, source_p->username, source_p->host,
209 –         source_p->localClient->send.bytes>>10,
210 –         source_p->localClient->recv.bytes>>10);
211 –    }
212 – #else
213 –  {
214 –    char linebuf[BUFSIZ];
215 –
216 –    /*
217 –     * This conditional makes the logfile active only after
218 –     * it's been created - thus logging can be turned off by
219 –     * removing the file.
220 –     * -Taner
221 –     */
222 –    if (IsClient(source_p))
223 –    {
224 –      if (user_log_fb == NULL)
225 –      {
226 –        if ((ConfigLoggingEntry.userlog[0] != '\0') &&
227 –           (user_log_fb = fbopen(ConfigLoggingEntry.userlog, "r")) != NULL)
228 –        {
229 –          fbclose(user_log_fb);
230 –          user_log_fb = fbopen(ConfigLoggingEntry.userlog, "a");
231 –        }
232 –      }
233 –
234 –      if (user_log_fb != NULL)
235 –      {
236 –        size_t nbytes = ircsprintf(linebuf,
237 –                   "%s (%3u:%02u:%02u): %s!%s@%s %llu/%llu\n",
238 –                   myctime(source_p->firsttime),
239 –                   (unsigned int)(on_for / 3600),
240 –                   (unsigned int)((on_for % 3600)/60),
241 –                   (unsigned int)(on_for % 60),
242 –                   source_p->name, source_p->username, source_p->host,
243 –                   source_p->localClient->send.bytes>>10,
244 –                   source_p->localClient->recv.bytes>>10);
245 –        fbputs(linebuf, user_log_fb, nbytes);
246 –      }
247 –    }
248 –  }
249 – #endif
250 – }
251 –
252 – #ifndef SYSLOG_USERS
253 – /* user_log_resync()
254 – *
255 – * inputs       - NONE
256 – * output       - NONE
257 – * side effects -
258 – */
259 – static void
260 – user_log_resync(void *notused)
261 – {
262 –  if (user_log_fb != NULL)
112    {
113 <    fbclose(user_log_fb);
265 <    user_log_fb = NULL;
266 <  }
267 < }
268 < #endif
113 >    write_log(type, buf);
114  
115 < /* log_oper_action()
271 < *
272 < * inputs       - type of oper log entry
273 < *              - pointer to oper
274 < *              - const char *pattern == format string
275 < *              - var args for format string
276 < * output       - none
277 < * side effects - corresponding log is written to, if its present.
278 < *
279 < * rewritten sept 5 2005 - Dianora
280 < */
281 < void
282 < log_oper_action(int log_type, const struct Client *source_p,
283 <                const char *pattern, ...)
284 < {
285 <  va_list args;
286 <  char linebuf[IRCD_BUFSIZE];
287 <  FBFILE *log_fb;
288 <  char *logfile;
289 <  const char *log_message;
290 <  size_t nbytes;
291 <  size_t n_preamble;
292 <  char *p;
293 <
294 <  switch(log_type)
295 <  {
296 <  case LOG_OPER_TYPE:
297 <    logfile = ConfigLoggingEntry.operlog;
298 <    log_message = "OPER";
299 <    break;
300 <  case LOG_FAILED_OPER_TYPE:
301 <    logfile = ConfigLoggingEntry.failed_operlog;
302 <    log_message = "FAILED OPER";
303 <    break;
304 <  case LOG_KLINE_TYPE:
305 <    logfile = ConfigLoggingEntry.klinelog;
306 <    log_message = "KLINE";
307 <    break;
308 <  case LOG_RKLINE_TYPE:
309 <    logfile = ConfigLoggingEntry.klinelog;
310 <    log_message = "RKLINE";
311 <    break;
312 <  case LOG_DLINE_TYPE:
313 <    logfile = ConfigLoggingEntry.klinelog;
314 <    log_message = "DLINE";
315 <    break;
316 <  case LOG_TEMP_DLINE_TYPE:
317 <    logfile = ConfigLoggingEntry.klinelog;
318 <    log_message = "TEMP DLINE";
319 <    break;
320 <  case LOG_TEMP_KLINE_TYPE:
321 <    logfile = ConfigLoggingEntry.klinelog;
322 <    log_message = "TEMP KLINE";
323 <    break;
324 <  case LOG_GLINE_TYPE:
325 <    logfile = ConfigLoggingEntry.glinelog;
326 <    log_message = "GLINE";
327 <    break;
328 <  case LOG_KILL_TYPE:
329 <    logfile = ConfigLoggingEntry.killlog;
330 <    log_message = "KILL";
331 <    break;
332 <  case LOG_IOERR_TYPE:
333 <    logfile = ConfigLoggingEntry.ioerrlog;
334 <    log_message = "IO ERR";
335 <    break;
336 <  default:
337 <    return;
338 <  }
339 <
340 <  if (*logfile == '\0')
341 <    return;
342 <
343 <  p = linebuf;
344 <  if (source_p != NULL)
345 <  {
346 <    n_preamble = ircsprintf(linebuf, "%s %s by (%s!%s@%s) :",
347 <                            myctime(CurrentTime), log_message,
348 <                            source_p->name, source_p->username, source_p->host);
349 <
350 <  }
351 <  else
352 <  {
353 <    n_preamble = ircsprintf(linebuf, "%s %s :",
354 <                            myctime(CurrentTime), log_message);
355 <  }
356 <
357 <  p += n_preamble;
358 <
359 <  if ((log_fb = fbopen(logfile, "r")) != NULL)
360 <  {
361 <    fbclose(log_fb);
362 <    log_fb = fbopen(logfile, "a");
363 <    if (log_fb == NULL)
115 >    if (log_exceed_size(type) <= 0)
116        return;
117 <    va_start(args, pattern);
118 <    /* XXX add check for IRCD_BUFSIZE-(n_preamble+1) < 0 ? -db */
119 <    nbytes = vsnprintf(p, IRCD_BUFSIZE-(n_preamble+1), pattern, args);
120 <    nbytes += n_preamble;
121 <    va_end(args);
122 <    fbputs(linebuf, log_fb, nbytes);
123 <    fbclose(log_fb);
117 >
118 >    snprintf(buf, sizeof(buf), "Rotating logfile %s",
119 >             log_type_table[type].path);
120 >    write_log(type, buf);
121 >    fbclose(log_type_table[type].file);
122 >    log_type_table[type].file = NULL;
123 >
124 >    snprintf(buf, sizeof(buf), "%s.old", log_type_table[type].path);
125 >    unlink(buf);
126 >    rename(log_type_table[type].path, buf);
127 >    log_add_file(type, log_type_table[type].size, log_type_table[type].path);
128    }
129   }

Diff Legend

– Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)