1 /* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
2 /* See LICENSE for licensing information */
8 typedef struct logfile_t
{
9 struct logfile_t
*next
;
17 static INLINE
const char *sev_to_string(int severity
) {
19 case LOG_DEBUG
: return "debug";
20 case LOG_INFO
: return "info";
21 case LOG_WARN
: return "warn";
22 case LOG_ERR
: return "err";
23 default: assert(0); return "UNKNOWN";
27 static int loglevel
= LOG_DEBUG
;
28 static logfile_t
*logfiles
= NULL
;
30 /* Format a log message into a fixed-sized buffer. (This is factored out
31 * of 'logv' so that we never format a message more than once.
33 static INLINE
void format_msg(char *buf
, size_t buf_len
,
34 int severity
, const char *funcname
,
35 const char *format
, va_list ap
)
41 buf_len
-= 2; /* subtract 2 characters so we have room for \n\0 */
43 tor_gettimeofday(&now
);
44 t
= (time_t)now
.tv_sec
;
46 n
= strftime(buf
, buf_len
, "%b %d %H:%M:%S", localtime(&t
));
47 n
+= snprintf(buf
+n
, buf_len
-n
,
49 (long)now
.tv_usec
/ 1000, sev_to_string(severity
));
51 n
= buf_len
-1; /* the *nprintf funcs return how many bytes they
52 * _would_ print, if the output is truncated.
53 * Subtract one because the count doesn't include the \0 */
56 n
+= snprintf(buf
+n
, buf_len
-n
, "%s(): ", funcname
);
61 n
+= vsnprintf(buf
+n
,buf_len
-n
,format
,ap
);
69 logv(int severity
, const char *funcname
, const char *format
, va_list ap
)
76 if (severity
< loglevel
)
78 for (lf
= logfiles
; lf
; lf
= lf
->next
) {
79 if (severity
< lf
->loglevel
|| severity
> lf
->max_loglevel
)
85 format_msg(buf
, 10024, severity
, funcname
, format
, ap
);
90 /* XXX check for EOF */
95 log_set_severity(int severity
)
100 /* Outputs a message to stdout */
101 void _log(int severity
, const char *format
, ...)
105 logv(severity
, NULL
, format
, ap
);
109 void _log_fn(int severity
, const char *fn
, const char *format
, ...)
113 logv(severity
, fn
, format
, ap
);
122 logfiles
= logfiles
->next
;
123 if (victim
->needs_close
)
124 fclose(victim
->file
);
132 for (lf
= logfiles
; lf
; lf
= lf
->next
) {
133 if (lf
->needs_close
) {
135 lf
->file
= fopen(lf
->filename
, "a");
140 void add_stream_log(int loglevel
, const char *name
, FILE *stream
)
143 lf
= tor_malloc(sizeof(logfile_t
));
146 lf
->loglevel
= loglevel
;
147 lf
->max_loglevel
= LOG_ERR
;
153 int add_file_log(int loglevel
, const char *filename
)
156 f
= fopen(filename
, "a");
158 add_stream_log(loglevel
, filename
, f
);
159 logfiles
->needs_close
= 1;