Commit a0c37b45 authored by Martin Mareš's avatar Martin Mareš

Logging is now configurable. You can define multiple log outputs (to both

files and syslog) and assign lists of message categories to each of them.
parent 7c0cc76e
......@@ -4,6 +4,9 @@
# Yet another comment
#log syslog { error };
#log "tmp" all;
#router id 62.168.0.1;
#define xyzzy = 120+10;
......
......@@ -44,9 +44,6 @@ void bug(char *msg, ...) NORET;
#define L_FATAL "\007" /* Fatal errors */
#define L_BUG "\010" /* BIRD bugs */
void log_init(char *); /* Initialize logging to given file (NULL=stderr, ""=syslog) */
void log_init_debug(char *); /* Initialize debug dump to given file (NULL=stderr, ""=off) */
void debug(char *msg, ...); /* Printf to debug output */
/* Debugging */
......
......@@ -4,6 +4,7 @@ timer.h
io.c
unix.h
endian.h
config.Y
krt.c
krt.h
......
/*
* BIRD -- UNIX Configuration
*
* (c) 1999 Martin Mares <mj@ucw.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
CF_HDR
#include "lib/unix.h"
CF_DECLS
CF_KEYWORDS(LOG, SYSLOG, ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
%type <i> log_mask log_mask_list log_cat
CF_GRAMMAR
CF_ADDTO(conf, log_config)
log_config: LOG TEXT log_mask ';' {
struct log_config *c = cfg_allocz(sizeof(struct log_config));
FILE *f = rfopen(new_config->pool, $2, "a");
if (!f) cf_error("Unable to open log file `%s': %m", $2);
c->mask = $3;
c->fh = f;
add_tail(&new_config->logfiles, &c->n);
}
| LOG SYSLOG log_mask ';' {
struct log_config *c = cfg_allocz(sizeof(struct log_config));
c->mask = $3;
add_tail(&new_config->logfiles, &c->n);
}
;
log_mask:
ALL { $$ = ~0; }
| '{' log_mask_list '}' { $$ = $2; }
;
log_mask_list:
log_cat { $$ = 1 << $1; }
| log_mask_list ',' log_cat { $$ = $1 | (1 << $3); }
;
log_cat:
DEBUG { $$ = L_DEBUG[0]; }
| TRACE { $$ = L_TRACE[0]; }
| INFO { $$ = L_INFO[0]; }
| REMOTE { $$ = L_REMOTE[0]; }
| WARNING { $$ = L_WARN[0]; }
| ERROR { $$ = L_ERR[0]; }
| AUTH { $$ = L_AUTH[0]; }
| FATAL { $$ = L_FATAL[0]; }
| BUG { $$ = L_BUG[0]; }
;
CF_CODE
CF_END
......@@ -14,21 +14,26 @@
#include "nest/bird.h"
#include "nest/cli.h"
#include "lib/string.h"
#include "lib/lists.h"
#include "lib/unix.h"
static int log_inited;
static FILE *logf = NULL;
static FILE *dbgf = NULL;
static list *current_log_list;
static list init_log_list;
#ifdef HAVE_SYSLOG
#include <sys/syslog.h>
static int syslog_priorities[] = {
LOG_INFO,
LOG_DEBUG,
LOG_DEBUG,
LOG_DEBUG,
LOG_INFO,
LOG_ERR,
LOG_WARNING,
LOG_ERR,
LOG_NOTICE,
LOG_ERR,
LOG_CRIT,
LOG_CRIT
};
#endif
......@@ -36,50 +41,55 @@ static int syslog_priorities[] = {
static char *class_names[] = {
"???",
"DBG",
"TRACE",
"INFO",
"RMT",
"WARN",
"ERR",
"AUTH",
"FATAL"
"FATAL",
"BUG"
};
static void
vlog(int class, char *msg, va_list args)
{
char buf[1024];
char date[32];
struct log_config *l;
if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0)
bsprintf(buf + sizeof(buf) - 100, " ... <too long>");
if (logf)
WALK_LIST(l, *current_log_list)
{
time_t now = time(NULL);
struct tm *tm = localtime(&now);
bsprintf(date, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
tm->tm_mday,
tm->tm_mon+1,
tm->tm_year+1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec,
class_names[class]);
fputs(date, logf);
fputs(buf, logf);
fputc('\n', logf);
fflush(logf);
}
if (!(l->mask & (1 << class)))
continue;
if (l->fh)
{
time_t now = time(NULL);
struct tm *tm = localtime(&now);
if (l->terminal_flag)
fputs("bird: ", l->fh);
else
{
fprintf(l->fh, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
tm->tm_mday,
tm->tm_mon+1,
tm->tm_year+1900,
tm->tm_hour,
tm->tm_min,
tm->tm_sec,
class_names[class]);
}
fputs(buf, l->fh);
fputc('\n', l->fh);
fflush(l->fh);
}
#ifdef HAVE_SYSLOG
else if (log_inited)
syslog(syslog_priorities[class], "%s", buf);
else
syslog(syslog_priorities[class], "%s", buf);
#endif
else
{
fputs("bird: ", stderr);
fputs(buf, stderr);
fputc('\n', stderr);
fflush(stderr);
}
cli_echo(class, buf);
}
......@@ -124,36 +134,40 @@ debug(char *msg, ...)
char buf[1024];
va_start(args, msg);
if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
if (dbgf)
fputs(buf, dbgf);
{
if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
fputs(buf, dbgf);
}
va_end(args);
}
void
log_init(char *f)
log_init(int debug)
{
FILE *new;
static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
init_list(&init_log_list);
current_log_list = &init_log_list;
if (!f)
new = stderr;
else if (!*f)
{
new = NULL;
#ifdef HAVE_SYSLOG
openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
#endif
}
else if (!(new = fopen(f, "a")))
if (!debug)
{
log(L_ERR "Unable to open log file `%s': %m", f);
return;
static struct log_config lc_syslog = { mask: ~0 };
openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
add_tail(current_log_list, &lc_syslog.n);
}
if (logf && logf != stderr)
fclose(logf);
logf = new;
log_inited = 1;
#endif
lc_stderr.fh = stderr;
add_tail(current_log_list, &lc_stderr.n);
}
void
log_switch(list *l)
{
current_log_list = l;
}
void
......@@ -162,9 +176,9 @@ log_init_debug(char *f)
if (dbgf && dbgf != stderr)
fclose(dbgf);
if (!f)
dbgf = stderr;
else if (!*f)
dbgf = NULL;
else if (!*f)
dbgf = stderr;
else if (!(dbgf = fopen(f, "a")))
log(L_ERR "Error opening debug file `%s': %m", f);
}
......@@ -67,6 +67,18 @@ cf_read(byte *dest, unsigned int len)
return l;
}
void
sysdep_preconfig(struct config *c)
{
init_list(&c->logfiles);
}
void
sysdep_commit(struct config *c)
{
log_switch(&c->logfiles);
}
static void
read_config(void)
{
......@@ -258,12 +270,13 @@ signal_init(void)
* Parsing of command-line arguments
*/
static char *opt_list = "c:d:";
static char *opt_list = "c:dD:";
static int debug_flag = 1; /* FIXME: Turn off for production use */
static void
usage(void)
{
fprintf(stderr, "Usage: bird [-c <config-file>] [-d <debug-file>]\n");
fprintf(stderr, "Usage: bird [-c <config-file>] [-d] [-D <debug-file>]\n");
exit(1);
}
......@@ -279,7 +292,11 @@ parse_args(int argc, char **argv)
config_name = optarg;
break;
case 'd':
debug_flag |= 1;
break;
case 'D':
log_init_debug(optarg);
debug_flag |= 2;
break;
default:
usage();
......@@ -300,10 +317,12 @@ main(int argc, char **argv)
dmalloc_debug(0x2f03d00);
#endif
log_init_debug(NULL);
setvbuf(stdout, NULL, _IONBF, 0); /* FIXME: Kill some day. */
setvbuf(stderr, NULL, _IONBF, 0);
parse_args(argc, argv);
if (debug_flag == 1)
log_init_debug("");
log_init(debug_flag);
log(L_INFO "Launching BIRD " BIRD_VERSION "...");
......
......@@ -9,6 +9,8 @@
#ifndef _BIRD_UNIX_H_
#define _BIRD_UNIX_H_
struct pool;
/* main.c */
void async_config(void);
......@@ -38,9 +40,23 @@ void io_loop(void);
void fill_in_sockaddr(sockaddr *sa, ip_addr a, unsigned port);
void get_sockaddr(sockaddr *sa, ip_addr *a, unsigned *port);
int sk_open_unix(struct birdsock *s, char *name);
void *tracked_fopen(struct pool *, char *name, char *mode);
/* krt.c bits */
void krt_io_init(void);
/* log.c */
void log_init(int debug);
void log_init_debug(char *); /* Initialize debug dump to given file (NULL=stderr, ""=off) */
void log_switch(struct list *);
struct log_config {
node n;
unsigned int mask; /* Classes to log */
void *fh; /* FILE to log to, NULL=syslog */
int terminal_flag;
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment