2 * BIRD Library -- Logging Functions
4 * (c) 1998--2000 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
12 * The Logging module offers a simple set of functions for writing
13 * messages to system logs and to the debug output. Message classes
14 * used by this module are described in |birdlib.h| and also in the
24 #include "nest/bird.h"
26 #include "nest/mrtdump.h"
27 #include "lib/string.h"
28 #include "lib/lists.h"
32 static list
*current_log_list
;
33 static char *current_syslog_name
; /* NULL -> syslog closed */
35 bird_clock_t rate_limit_time
= 5;
36 int rate_limit_count
= 5;
39 #include <sys/syslog.h>
41 static int syslog_priorities
[] = {
55 static char *class_names
[] = {
69 vlog(int class, char *msg
, va_list args
)
74 if (bvsnprintf(buf
, sizeof(buf
)-1, msg
, args
) < 0)
75 bsprintf(buf
+ sizeof(buf
) - 100, " ... <too long>");
77 WALK_LIST(l
, *current_log_list
)
79 if (!(l
->mask
& (1 << class)))
84 fputs("bird: ", l
->fh
);
87 byte tbuf
[TM_DATETIME_BUFFER_SIZE
];
88 tm_format_datetime(tbuf
, &config
->tf_log
, now
);
89 fprintf(l
->fh
, "%s <%s> ", tbuf
, class_names
[class]);
97 syslog(syslog_priorities
[class], "%s", buf
);
100 cli_echo(class, buf
);
104 * log - log a message
105 * @msg: printf-like formatting string with message class information
106 * prepended (%L_DEBUG to %L_BUG, see |lib/birdlib.h|)
108 * This function formats a message according to the format string @msg
109 * and writes it to the corresponding log file (as specified in the
110 * configuration). Please note that the message is automatically
111 * formatted as a full line, no need to include |\n| inside.
114 log_msg(char *msg
, ...)
120 if (*msg
>= 1 && *msg
<= 8)
122 vlog(class, msg
, args
);
127 log_rl(struct rate_limit
*rl
, char *msg
, ...)
132 bird_clock_t delta
= now
- rl
->timestamp
;
133 if ((0 <= delta
) && (delta
< rate_limit_time
))
143 if (rl
->count
> rate_limit_count
)
147 if (*msg
>= 1 && *msg
<= 8)
149 vlog(class, msg
, args
);
150 if (rl
->count
== rate_limit_count
)
151 vlog(class, "...", args
);
156 * bug - report an internal error
157 * @msg: a printf-like error message
159 * This function logs an internal error and aborts execution
168 vlog(L_BUG
[0], msg
, args
);
173 * bug - report a fatal error
174 * @msg: a printf-like error message
176 * This function logs a fatal error and aborts execution
185 vlog(L_FATAL
[0], msg
, args
);
190 * debug - write to debug output
191 * @msg: a printf-like message
193 * This function formats the message @msg and prints it out
194 * to the debugging output. No newline character is appended.
197 debug(char *msg
, ...)
205 if (bvsnprintf(buf
, sizeof(buf
), msg
, args
) < 0)
206 bsprintf(buf
+ sizeof(buf
) - 100, " ... <too long>\n");
213 default_log_list(int debug
, int init
, char **syslog_name
)
215 static list init_log_list
;
216 init_list(&init_log_list
);
222 static struct log_config lc_syslog
= { mask
: ~0 };
223 add_tail(&init_log_list
, &lc_syslog
.n
);
224 *syslog_name
= bird_name
;
226 return &init_log_list
;
230 static struct log_config lc_stderr
= { mask
: ~0, terminal_flag
: 1 };
231 lc_stderr
.fh
= stderr
;
232 add_tail(&init_log_list
, &lc_stderr
.n
);
233 return &init_log_list
;
237 log_switch(int debug
, list
*l
, char *new_syslog_name
)
239 if (!l
|| EMPTY_LIST(*l
))
240 l
= default_log_list(debug
, !l
, &new_syslog_name
);
242 current_log_list
= l
;
245 if (current_syslog_name
&& new_syslog_name
&&
246 !strcmp(current_syslog_name
, new_syslog_name
))
249 if (current_syslog_name
)
253 openlog(new_syslog_name
, LOG_CONS
| LOG_NDELAY
, LOG_DAEMON
);
255 current_syslog_name
= new_syslog_name
;
262 log_init_debug(char *f
)
264 if (dbgf
&& dbgf
!= stderr
)
270 else if (!(dbgf
= fopen(f
, "a")))
271 log(L_ERR
"Error opening debug file `%s': %m", f
);
273 setvbuf(dbgf
, NULL
, _IONBF
, 0);
277 mrt_dump_message(struct proto
*p
, u16 type
, u16 subtype
, byte
*buf
, u32 len
)
280 put_u32(buf
+0, now_real
);
281 put_u16(buf
+4, type
);
282 put_u16(buf
+6, subtype
);
283 put_u32(buf
+8, len
- MRTDUMP_HDR_LENGTH
);
285 if (p
->cf
->global
->mrtdump_file
!= -1)
286 write(p
->cf
->global
->mrtdump_file
, buf
, len
);