Statistics
| Branch: | Revision:

iof-bird-daemon / sysdep / unix / log.c @ 725270cb

History | View | Annotate | Download (4.27 KB)

1 6032aa6a Martin Mares
/*
2
 *        BIRD Library -- Logging Functions
3
 *
4 73275d85 Martin Mares
 *        (c) 1998--2000 Martin Mares <mj@ucw.cz>
5 6032aa6a Martin Mares
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9 73275d85 Martin Mares
/**
10
 * DOC: Logging
11
 *
12
 * The Logging module offers a simple set of functions for writing
13 725270cb Martin Mares
 * 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
15
 * user's manual.
16 73275d85 Martin Mares
 */
17
18 6032aa6a Martin Mares
#include <stdio.h>
19
#include <stdlib.h>
20
#include <stdarg.h>
21
#include <sys/time.h>
22
23
#include "nest/bird.h"
24 34350a52 Martin Mares
#include "nest/cli.h"
25 9556f225 Martin Mares
#include "lib/string.h"
26 a0c37b45 Martin Mares
#include "lib/lists.h"
27
#include "lib/unix.h"
28 6032aa6a Martin Mares
29
static FILE *dbgf = NULL;
30 a0c37b45 Martin Mares
static list *current_log_list;
31
static list init_log_list;
32 6032aa6a Martin Mares
33
#ifdef HAVE_SYSLOG
34
#include <sys/syslog.h>
35
36
static int syslog_priorities[] = {
37 a0c37b45 Martin Mares
  LOG_DEBUG,
38
  LOG_DEBUG,
39 6032aa6a Martin Mares
  LOG_DEBUG,
40
  LOG_INFO,
41 a0c37b45 Martin Mares
  LOG_ERR,
42 6032aa6a Martin Mares
  LOG_WARNING,
43
  LOG_ERR,
44 a0c37b45 Martin Mares
  LOG_ERR,
45
  LOG_CRIT,
46 6032aa6a Martin Mares
  LOG_CRIT
47
};
48
#endif
49
50
static char *class_names[] = {
51
  "???",
52
  "DBG",
53 a0c37b45 Martin Mares
  "TRACE",
54 6032aa6a Martin Mares
  "INFO",
55 a0c37b45 Martin Mares
  "RMT",
56 6032aa6a Martin Mares
  "WARN",
57
  "ERR",
58
  "AUTH",
59 a0c37b45 Martin Mares
  "FATAL",
60
  "BUG"
61 6032aa6a Martin Mares
};
62
63 9556f225 Martin Mares
static void
64 34350a52 Martin Mares
vlog(int class, char *msg, va_list args)
65 9556f225 Martin Mares
{
66 34350a52 Martin Mares
  char buf[1024];
67 a0c37b45 Martin Mares
  struct log_config *l;
68 9556f225 Martin Mares
69 34350a52 Martin Mares
  if (bvsnprintf(buf, sizeof(buf)-1, msg, args) < 0)
70
    bsprintf(buf + sizeof(buf) - 100, " ... <too long>");
71 9556f225 Martin Mares
72 a0c37b45 Martin Mares
  WALK_LIST(l, *current_log_list)
73 6032aa6a Martin Mares
    {
74 a0c37b45 Martin Mares
      if (!(l->mask & (1 << class)))
75
        continue;
76
      if (l->fh)
77
        {
78
          time_t now = time(NULL);
79
          struct tm *tm = localtime(&now);
80
81
          if (l->terminal_flag)
82
            fputs("bird: ", l->fh);
83
          else
84
            {
85
              fprintf(l->fh, "%02d-%02d-%04d %02d:%02d:%02d <%s> ",
86
                       tm->tm_mday,
87
                       tm->tm_mon+1,
88
                       tm->tm_year+1900,
89
                       tm->tm_hour,
90
                       tm->tm_min,
91
                       tm->tm_sec,
92
                       class_names[class]);
93
            }
94
          fputs(buf, l->fh);
95
          fputc('\n', l->fh);
96
          fflush(l->fh);
97
        }
98 6032aa6a Martin Mares
#ifdef HAVE_SYSLOG
99 a0c37b45 Martin Mares
      else
100
        syslog(syslog_priorities[class], "%s", buf);
101 6032aa6a Martin Mares
#endif
102
    }
103 34350a52 Martin Mares
  cli_echo(class, buf);
104 6032aa6a Martin Mares
}
105
106 73275d85 Martin Mares
/**
107
 * log - log a message
108
 * @msg: printf-like formatting string with message class information
109
 * prepended (%L_DEBUG to %L_BUG, see |lib/birdlib.h|)
110
 *
111
 * This function formats a message according to the format string @msg
112 2e9b2421 Martin Mares
 * and writes it to the corresponding log file (as specified in the
113 73275d85 Martin Mares
 * configuration). Please note that the message is automatically
114
 * formatted as a full line, no need to include |\n| inside.
115
 */
116 6032aa6a Martin Mares
void
117
log(char *msg, ...)
118
{
119
  int class = 1;
120
  va_list args;
121
122
  va_start(args, msg);
123 98e87c86 Martin Mares
  if (*msg >= 1 && *msg <= 8)
124 6032aa6a Martin Mares
    class = *msg++;
125
  vlog(class, msg, args);
126
  va_end(args);
127
}
128
129 73275d85 Martin Mares
/**
130
 * bug - report an internal error
131
 * @msg: a printf-like error message
132
 *
133
 * This function logs an internal error and aborts execution
134
 * of the program.
135
 */
136 6032aa6a Martin Mares
void
137 98e87c86 Martin Mares
bug(char *msg, ...)
138
{
139
  va_list args;
140
141
  va_start(args, msg);
142
  vlog(L_BUG[0], msg, args);
143 818ff1e2 Martin Mares
  abort();
144 98e87c86 Martin Mares
}
145
146 73275d85 Martin Mares
/**
147
 * bug - report a fatal error
148
 * @msg: a printf-like error message
149
 *
150
 * This function logs a fatal error and aborts execution
151
 * of the program.
152
 */
153 98e87c86 Martin Mares
void
154 6032aa6a Martin Mares
die(char *msg, ...)
155
{
156
  va_list args;
157
158
  va_start(args, msg);
159 98e87c86 Martin Mares
  vlog(L_FATAL[0], msg, args);
160 6032aa6a Martin Mares
  exit(1);
161
}
162
163 73275d85 Martin Mares
/**
164
 * debug - write to debug output
165
 * @msg: a printf-like message
166
 *
167
 * This function formats the message @msg and prints it out
168
 * to the debugging output. No newline character is appended.
169
 */
170 6032aa6a Martin Mares
void
171
debug(char *msg, ...)
172
{
173
  va_list args;
174 34350a52 Martin Mares
  char buf[1024];
175 6032aa6a Martin Mares
176
  va_start(args, msg);
177
  if (dbgf)
178 a0c37b45 Martin Mares
    {
179
      if (bvsnprintf(buf, sizeof(buf), msg, args) < 0)
180
        bsprintf(buf + sizeof(buf) - 100, " ... <too long>\n");
181
      fputs(buf, dbgf);
182
    }
183 6032aa6a Martin Mares
  va_end(args);
184
}
185
186
void
187 a0c37b45 Martin Mares
log_init(int debug)
188 6032aa6a Martin Mares
{
189 a0c37b45 Martin Mares
  static struct log_config lc_stderr = { mask: ~0, terminal_flag: 1 };
190
191
  init_list(&init_log_list);
192
  current_log_list = &init_log_list;
193 6032aa6a Martin Mares
194
#ifdef HAVE_SYSLOG
195 a0c37b45 Martin Mares
  if (!debug)
196 6032aa6a Martin Mares
    {
197 a0c37b45 Martin Mares
      static struct log_config lc_syslog = { mask: ~0 };
198
      openlog("bird", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
199
      add_tail(current_log_list, &lc_syslog.n);
200 6032aa6a Martin Mares
    }
201 a0c37b45 Martin Mares
#endif
202
203
  lc_stderr.fh = stderr;
204
  add_tail(current_log_list, &lc_stderr.n);
205
}
206
207
void
208
log_switch(list *l)
209
{
210 f78056fb Martin Mares
  if (EMPTY_LIST(*l))
211
    current_log_list = &init_log_list;
212
  else
213
    current_log_list = l;
214 6032aa6a Martin Mares
}
215
216
void
217
log_init_debug(char *f)
218
{
219
  if (dbgf && dbgf != stderr)
220
    fclose(dbgf);
221
  if (!f)
222
    dbgf = NULL;
223 a0c37b45 Martin Mares
  else if (!*f)
224
    dbgf = stderr;
225 6032aa6a Martin Mares
  else if (!(dbgf = fopen(f, "a")))
226
    log(L_ERR "Error opening debug file `%s': %m", f);
227 f098e072 Martin Mares
  if (dbgf)
228
    setvbuf(dbgf, NULL, _IONBF, 0);
229 6032aa6a Martin Mares
}