blob: b51be7d6df16caa4cf6a69289da69bd1219da1e5 [file] [log] [blame]
Harald Welte3fb0b6f2010-05-19 19:02:52 +02001/* OpenBSC logging helper for the VTY */
2/* (C) 2009-2010 by Harald Welte <laforge@gnumonks.org>
3 * (C) 2009-2010 by Holger Hans Peter Freyther
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 */
21
22#include <stdlib.h>
23#include <string.h>
24
Harald Welte28222962011-02-18 20:37:04 +010025#include "../../config.h"
26
Harald Welte3fb0b6f2010-05-19 19:02:52 +020027#include <osmocore/talloc.h>
28#include <osmocore/logging.h>
Harald Welte28222962011-02-18 20:37:04 +010029#include <osmocore/utils.h>
Harald Welte3fb0b6f2010-05-19 19:02:52 +020030
31//#include <openbsc/vty.h>
32
33#include <osmocom/vty/command.h>
34#include <osmocom/vty/buffer.h>
35#include <osmocom/vty/vty.h>
36#include <osmocom/vty/telnet_interface.h>
37#include <osmocom/vty/logging.h>
38
Harald Welte28222962011-02-18 20:37:04 +010039#define LOG_STR "Configure logging sub-system\n"
40
Harald Welte4ebdf742010-05-19 19:54:00 +020041extern const struct log_info *osmo_log_info;
Harald Welte3fb0b6f2010-05-19 19:02:52 +020042
Harald Welte76e72ab2011-02-17 15:52:39 +010043static void _vty_output(struct log_target *tgt,
44 unsigned int level, const char *line)
Harald Welte3fb0b6f2010-05-19 19:02:52 +020045{
46 struct vty *vty = tgt->tgt_vty.vty;
47 vty_out(vty, "%s", line);
48 /* This is an ugly hack, but there is no easy way... */
49 if (strchr(line, '\n'))
50 vty_out(vty, "\r");
51}
52
53struct log_target *log_target_create_vty(struct vty *vty)
54{
55 struct log_target *target;
56
57 target = log_target_create();
58 if (!target)
59 return NULL;
60
61 target->tgt_vty.vty = vty;
62 target->output = _vty_output;
63 return target;
64}
65
66DEFUN(enable_logging,
67 enable_logging_cmd,
68 "logging enable",
69 LOGGING_STR
70 "Enables logging to this vty\n")
71{
72 struct telnet_connection *conn;
73
74 conn = (struct telnet_connection *) vty->priv;
75 if (conn->dbg) {
76 vty_out(vty, "Logging already enabled.%s", VTY_NEWLINE);
77 return CMD_WARNING;
78 }
79
80 conn->dbg = log_target_create_vty(vty);
81 if (!conn->dbg)
82 return CMD_WARNING;
83
84 log_add_target(conn->dbg);
85 return CMD_SUCCESS;
86}
87
88DEFUN(logging_fltr_all,
89 logging_fltr_all_cmd,
90 "logging filter all (0|1)",
91 LOGGING_STR FILTER_STR
92 "Do you want to log all messages?\n"
93 "Only print messages matched by other filters\n"
94 "Bypass filter and print all messages\n")
95{
96 struct telnet_connection *conn;
97
98 conn = (struct telnet_connection *) vty->priv;
99 if (!conn->dbg) {
100 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
101 return CMD_WARNING;
102 }
103
104 log_set_all_filter(conn->dbg, atoi(argv[0]));
105 return CMD_SUCCESS;
106}
107
108DEFUN(logging_use_clr,
109 logging_use_clr_cmd,
110 "logging color (0|1)",
111 LOGGING_STR "Configure color-printing for log messages\n"
112 "Don't use color for printing messages\n"
113 "Use color for printing messages\n")
114{
115 struct telnet_connection *conn;
116
117 conn = (struct telnet_connection *) vty->priv;
118 if (!conn->dbg) {
119 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
120 return CMD_WARNING;
121 }
122
123 log_set_use_color(conn->dbg, atoi(argv[0]));
124 return CMD_SUCCESS;
125}
126
127DEFUN(logging_prnt_timestamp,
128 logging_prnt_timestamp_cmd,
129 "logging timestamp (0|1)",
130 LOGGING_STR "Configure log message timestamping\n"
131 "Don't prefix each log message\n"
132 "Prefix each log message with current timestamp\n")
133{
134 struct telnet_connection *conn;
135
136 conn = (struct telnet_connection *) vty->priv;
137 if (!conn->dbg) {
138 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
139 return CMD_WARNING;
140 }
141
142 log_set_print_timestamp(conn->dbg, atoi(argv[0]));
143 return CMD_SUCCESS;
144}
145
146/* FIXME: those have to be kept in sync with the log levels and categories */
Holger Hans Peter Freyther549fbb82011-01-22 23:17:21 +0100147#define VTY_DEBUG_CATEGORIES "(rll|cc|mm|rr|rsl|nm|sms|pag|mncc|inp|mi|mib|mux|meas|sccp|msc|mgcp|ho|db|ref|gprs|ns|bssgp|llc|sndcp|isup|m2ua|pcap|all)"
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200148#define CATEGORIES_HELP \
149 "A-bis Radio Link Layer (RLL)\n" \
150 "Layer3 Call Control (CC)\n" \
151 "Layer3 Mobility Management (MM)\n" \
152 "Layer3 Radio Resource (RR)\n" \
153 "A-bis Radio Signalling Link (RSL)\n" \
154 "A-bis Network Management / O&M (NM/OML)\n" \
155 "Layer3 Short Messagaging Service (SMS)\n" \
156 "Paging Subsystem\n" \
157 "MNCC API for Call Control application\n" \
158 "A-bis Input Subsystem\n" \
159 "A-bis Input Driver for Signalling\n" \
160 "A-bis Input Driver for B-Channel (voice data)\n" \
161 "A-bis B-Channel / Sub-channel Multiplexer\n" \
162 "Radio Measurements\n" \
163 "SCCP\n" \
164 "Mobile Switching Center\n" \
165 "Media Gateway Control Protocol\n" \
166 "Hand-over\n" \
167 "Database Layer\n" \
168 "Reference Counting\n" \
169 "GPRS Core\n" \
170 "GPRS Network Service (NS)\n" \
171 "GPRS BSS Gateway Protocol (BSSGP)\n" \
172 "GPRS Logical Link Control Protocol (LLC)\n" \
173 "GPRS Sub-Network Dependent Control Protocol (SNDCP)\n" \
Holger Hans Peter Freyther549fbb82011-01-22 23:17:21 +0100174 "ISDN User Part (ISUP)\n" \
175 "SCTP M2UA\n" \
176 "Trace message IO\n" \
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200177 "Global setting for all subsytems\n"
178
179#define VTY_DEBUG_LEVELS "(everything|debug|info|notice|error|fatal)"
180#define LEVELS_HELP \
181 "Log simply everything\n" \
182 "Log debug messages and higher levels\n" \
183 "Log informational messages and higher levels\n" \
184 "Log noticable messages and higher levels\n" \
185 "Log error messages and higher levels\n" \
186 "Log only fatal messages\n"
Harald Welte28222962011-02-18 20:37:04 +0100187
188static int _logging_level(struct vty *vty, struct log_target *dbg,
189 const char *cat_str, const char *lvl_str)
190{
191 int category = log_parse_category(cat_str);
192 int level = log_parse_level(lvl_str);
193
194 if (level < 0) {
195 vty_out(vty, "Invalid level `%s'%s", lvl_str, VTY_NEWLINE);
196 return CMD_WARNING;
197 }
198
199 /* Check for special case where we want to set global log level */
200 if (!strcmp(cat_str, "all")) {
201 log_set_log_level(dbg, level);
202 return CMD_SUCCESS;
203 }
204
205 if (category < 0) {
206 vty_out(vty, "Invalid category `%s'%s", cat_str, VTY_NEWLINE);
207 return CMD_WARNING;
208 }
209
210 dbg->categories[category].enabled = 1;
211 dbg->categories[category].loglevel = level;
212
213 return CMD_SUCCESS;
214}
215
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200216DEFUN(logging_level,
217 logging_level_cmd,
218 "logging level " VTY_DEBUG_CATEGORIES " " VTY_DEBUG_LEVELS,
219 LOGGING_STR
220 "Set the log level for a specified category\n"
221 CATEGORIES_HELP
222 LEVELS_HELP)
223{
224 struct telnet_connection *conn;
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200225
226 conn = (struct telnet_connection *) vty->priv;
227 if (!conn->dbg) {
228 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
229 return CMD_WARNING;
230 }
231
Harald Welte28222962011-02-18 20:37:04 +0100232 return _logging_level(vty, conn->dbg, argv[0], argv[1]);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200233}
234
235DEFUN(logging_set_category_mask,
236 logging_set_category_mask_cmd,
237 "logging set log mask MASK",
238 LOGGING_STR
239 "Decide which categories to output.\n")
240{
241 struct telnet_connection *conn;
242
243 conn = (struct telnet_connection *) vty->priv;
244 if (!conn->dbg) {
245 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
246 return CMD_WARNING;
247 }
248
249 log_parse_category_mask(conn->dbg, argv[0]);
250 return CMD_SUCCESS;
251}
252
253DEFUN(diable_logging,
254 disable_logging_cmd,
255 "logging disable",
256 LOGGING_STR
257 "Disables logging to this vty\n")
258{
259 struct telnet_connection *conn;
260
261 conn = (struct telnet_connection *) vty->priv;
262 if (!conn->dbg) {
263 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
264 return CMD_WARNING;
265 }
266
267 log_del_target(conn->dbg);
268 talloc_free(conn->dbg);
269 conn->dbg = NULL;
270 return CMD_SUCCESS;
271}
272
273static void vty_print_logtarget(struct vty *vty, const struct log_info *info,
274 const struct log_target *tgt)
275{
276 unsigned int i;
277
278 vty_out(vty, " Global Loglevel: %s%s",
279 log_level_str(tgt->loglevel), VTY_NEWLINE);
280 vty_out(vty, " Use color: %s, Print Timestamp: %s%s",
281 tgt->use_color ? "On" : "Off",
282 tgt->print_timestamp ? "On" : "Off", VTY_NEWLINE);
283
284 vty_out(vty, " Log Level specific information:%s", VTY_NEWLINE);
285
286 for (i = 0; i < info->num_cat; i++) {
287 const struct log_category *cat = &tgt->categories[i];
288 vty_out(vty, " %-10s %-10s %-8s %s%s",
289 info->cat[i].name+1, log_level_str(cat->loglevel),
290 cat->enabled ? "Enabled" : "Disabled",
291 info->cat[i].description,
292 VTY_NEWLINE);
293 }
294}
295
296#define SHOW_LOG_STR "Show current logging configuration\n"
297
298DEFUN(show_logging_vty,
299 show_logging_vty_cmd,
300 "show logging vty",
301 SHOW_STR SHOW_LOG_STR
302 "Show current logging configuration for this vty\n")
303{
304 struct telnet_connection *conn;
305
306 conn = (struct telnet_connection *) vty->priv;
307 if (!conn->dbg) {
308 vty_out(vty, "Logging was not enabled.%s", VTY_NEWLINE);
309 return CMD_WARNING;
310 }
Harald Welte4ebdf742010-05-19 19:54:00 +0200311 vty_print_logtarget(vty, osmo_log_info, conn->dbg);
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200312
313 return CMD_SUCCESS;
314}
315
316gDEFUN(cfg_description, cfg_description_cmd,
317 "description .TEXT",
318 "Save human-readable decription of the object\n")
319{
320 char **dptr = vty->index_sub;
321
322 if (!dptr) {
323 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
324 return CMD_WARNING;
325 }
326
327 *dptr = argv_concat(argv, argc, 0);
328 if (!dptr)
329 return CMD_WARNING;
330
331 return CMD_SUCCESS;
332}
333
334gDEFUN(cfg_no_description, cfg_no_description_cmd,
335 "no description",
336 NO_STR
337 "Remove description of the object\n")
338{
339 char **dptr = vty->index_sub;
340
341 if (!dptr) {
342 vty_out(vty, "vty->index_sub == NULL%s", VTY_NEWLINE);
343 return CMD_WARNING;
344 }
345
346 if (*dptr) {
347 talloc_free(*dptr);
348 *dptr = NULL;
349 }
350
351 return CMD_SUCCESS;
352}
353
Harald Welte28222962011-02-18 20:37:04 +0100354/* Support for configuration of log targets != the current vty */
355
356struct cmd_node cfg_log_node = {
357 CFG_LOG_NODE,
358 "%s(config-log)# ",
359 1
360};
361
362DEFUN(cfg_log_fltr_all,
363 cfg_log_fltr_all_cmd,
364 "logging filter all (0|1)",
365 LOGGING_STR FILTER_STR
366 "Do you want to log all messages?\n"
367 "Only print messages matched by other filters\n"
368 "Bypass filter and print all messages\n")
369{
370 struct log_target *dbg = vty->index;
371
372 log_set_all_filter(dbg, atoi(argv[0]));
373 return CMD_SUCCESS;
374}
375
376DEFUN(cfg_log_use_clr,
377 cfg_log_use_clr_cmd,
378 "logging color (0|1)",
379 LOGGING_STR "Configure color-printing for log messages\n"
380 "Don't use color for printing messages\n"
381 "Use color for printing messages\n")
382{
383 struct log_target *dbg = vty->index;
384
385 log_set_use_color(dbg, atoi(argv[0]));
386 return CMD_SUCCESS;
387}
388
389DEFUN(cfg_log_timestamp,
390 cfg_log_timestamp_cmd,
391 "logging timestamp (0|1)",
392 LOGGING_STR "Configure log message timestamping\n"
393 "Don't prefix each log message\n"
394 "Prefix each log message with current timestamp\n")
395{
396 struct log_target *dbg = vty->index;
397
398 log_set_print_timestamp(dbg, atoi(argv[0]));
399 return CMD_SUCCESS;
400}
401
402DEFUN(cfg_log_level,
403 cfg_log_level_cmd,
404 "logging level " VTY_DEBUG_CATEGORIES " " VTY_DEBUG_LEVELS,
405 LOGGING_STR
406 "Set the log level for a specified category\n"
407 CATEGORIES_HELP
408 LEVELS_HELP)
409{
410 struct log_target *dbg = vty->index;
411
412 return _logging_level(vty, dbg, argv[0], argv[1]);
413}
414
415#ifdef HAVE_SYSLOG_H
416
417#include <syslog.h>
418
419static const int local_sysl_map[] = {
420 [0] = LOG_LOCAL0,
421 [1] = LOG_LOCAL1,
422 [2] = LOG_LOCAL2,
423 [3] = LOG_LOCAL3,
424 [4] = LOG_LOCAL4,
425 [5] = LOG_LOCAL5,
426 [6] = LOG_LOCAL6,
427 [7] = LOG_LOCAL7
428};
429
430static int _cfg_log_syslog(struct vty *vty, int facility)
431{
432 struct log_target *tgt;
433
434 /* First delete the old syslog target, if any */
435 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
436 if (tgt)
437 log_target_destroy(tgt);
438
439 tgt = log_target_create_syslog("FIXME", 0, facility);
440 if (!tgt) {
441 vty_out(vty, "%% Unable to open syslog%s", VTY_NEWLINE);
442 return CMD_WARNING;
443 }
444 log_add_target(tgt);
445
446 vty->index = tgt;
447 vty->node = CFG_LOG_NODE;
448
449 return CMD_SUCCESS;
450}
451
452DEFUN(cfg_log_syslog_local, cfg_log_syslog_local_cmd,
453 "log syslog local <0-7>",
454 LOG_STR "Logging via syslog\n" "Syslog LOCAL facility\n"
455 "Local facility number\n")
456{
457 int local = atoi(argv[0]);
458 int facility = local_sysl_map[local];
459
460 return _cfg_log_syslog(vty, facility);
461}
462
463static struct value_string sysl_level_names[] = {
464 { LOG_AUTHPRIV, "authpriv" },
465 { LOG_CRON, "cron" },
466 { LOG_DAEMON, "daemon" },
467 { LOG_FTP, "ftp" },
468 { LOG_LPR, "lpr" },
469 { LOG_MAIL, "mail" },
470 { LOG_NEWS, "news" },
471 { LOG_USER, "user" },
472 { LOG_UUCP, "uucp" },
473 /* only for value -> string conversion */
474 { LOG_LOCAL0, "local 0" },
475 { LOG_LOCAL1, "local 1" },
476 { LOG_LOCAL2, "local 2" },
477 { LOG_LOCAL3, "local 3" },
478 { LOG_LOCAL4, "local 4" },
479 { LOG_LOCAL5, "local 5" },
480 { LOG_LOCAL6, "local 6" },
481 { LOG_LOCAL7, "local 7" },
482 { 0, NULL }
483};
484
485DEFUN(cfg_log_syslog, cfg_log_syslog_cmd,
486 "log syslog (authpriv|cron|daemon|ftp|lpr|mail|news|user|uucp)",
487 LOG_STR "Logging via syslog\n")
488{
489 int facility = get_string_value(sysl_level_names, argv[0]);
490
491 return _cfg_log_syslog(vty, facility);
492}
493
494DEFUN(cfg_no_log_syslog, cfg_no_log_syslog_cmd,
495 "no log syslog",
496 NO_STR LOG_STR "Logging via syslog\n")
497{
498 struct log_target *tgt;
499
500 tgt = log_target_find(LOG_TGT_TYPE_SYSLOG, NULL);
501 if (!tgt) {
502 vty_out(vty, "%% No syslog target found%s",
503 VTY_NEWLINE);
504 return CMD_WARNING;
505 }
506
507 log_target_destroy(tgt);
508
509 return CMD_SUCCESS;
510}
511#endif /* HAVE_SYSLOG_H */
512
513DEFUN(cfg_log_stderr, cfg_log_stderr_cmd,
514 "log stderr",
515 LOG_STR "Logging via STDERR of the process\n")
516{
517 struct log_target *tgt;
518
519 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
520 if (!tgt) {
521 tgt = log_target_create_stderr();
522 if (!tgt) {
523 vty_out(vty, "%% Unable to create stderr log%s",
524 VTY_NEWLINE);
525 return CMD_WARNING;
526 }
527 log_add_target(tgt);
528 }
529
530 vty->index = tgt;
531 vty->node = CFG_LOG_NODE;
532
533 return CMD_SUCCESS;
534}
535
536DEFUN(cfg_no_log_stderr, cfg_no_log_stderr_cmd,
537 "no log stderr",
538 NO_STR LOG_STR "Logging via STDERR of the process\n")
539{
540 struct log_target *tgt;
541
542 tgt = log_target_find(LOG_TGT_TYPE_STDERR, NULL);
543 if (!tgt) {
544 vty_out(vty, "%% No stderr logging active%s", VTY_NEWLINE);
545 return CMD_WARNING;
546 }
547
548 log_target_destroy(tgt);
549
550 return CMD_SUCCESS;
551}
552
553DEFUN(cfg_log_file, cfg_log_file_cmd,
554 "log file .FILENAME",
555 LOG_STR "Logging to text file\n" "Filename\n")
556{
557 const char *fname = argv[0];
558 struct log_target *tgt;
559
560 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
561 if (!tgt) {
562 tgt = log_target_create_file(fname);
563 if (!tgt) {
564 vty_out(vty, "%% Unable to create file `%s'%s",
565 fname, VTY_NEWLINE);
566 return CMD_WARNING;
567 }
568 log_add_target(tgt);
569 }
570
571 vty->index = tgt;
572 vty->node = CFG_LOG_NODE;
573
574 return CMD_SUCCESS;
575}
576
577
578DEFUN(cfg_no_log_file, cfg_no_log_file_cmd,
579 "no log file .FILENAME",
580 NO_STR LOG_STR "Logging to text file\n" "Filename\n")
581{
582 const char *fname = argv[0];
583 struct log_target *tgt;
584
585 tgt = log_target_find(LOG_TGT_TYPE_FILE, fname);
586 if (!tgt) {
587 vty_out(vty, "%% No such log file `%s'%s",
588 fname, VTY_NEWLINE);
589 return CMD_WARNING;
590 }
591
592 log_target_destroy(tgt);
593
594 return CMD_SUCCESS;
595}
596
597static int config_write_log_single(struct vty *vty, struct log_target *tgt)
598{
599 int i;
600 char level_lower[32];
601
602 switch (tgt->type) {
603 case LOG_TGT_TYPE_VTY:
604 return 1;
605 break;
606 case LOG_TGT_TYPE_STDERR:
607 vty_out(vty, "log stderr%s", VTY_NEWLINE);
608 break;
609 case LOG_TGT_TYPE_SYSLOG:
610#ifdef HAVE_SYSLOG_H
611 vty_out(vty, "log syslog %s%s",
612 get_value_string(sysl_level_names,
613 tgt->tgt_syslog.facility),
614 VTY_NEWLINE);
615#endif
616 break;
617 case LOG_TGT_TYPE_FILE:
618 vty_out(vty, "log file %s%s", tgt->tgt_file.fname, VTY_NEWLINE);
619 break;
620 }
621
622 vty_out(vty, " logging color %u%s", tgt->use_color ? 1 : 0,
623 VTY_NEWLINE);
624 vty_out(vty, " logging timestamp %u%s", tgt->print_timestamp ? 1 : 0,
625 VTY_NEWLINE);
626
627 /* stupid old osmo logging API uses uppercase strings... */
628 osmo_str2lower(level_lower, log_level_str(tgt->loglevel));
629 vty_out(vty, " logging level all %s%s", level_lower, VTY_NEWLINE);
630
631 for (i = 0; i < osmo_log_info->num_cat; i++) {
632 const struct log_category *cat = &tgt->categories[i];
633 char cat_lower[32];
634
635 /* stupid old osmo logging API uses uppercase strings... */
636 osmo_str2lower(cat_lower, osmo_log_info->cat[i].name+1);
637 osmo_str2lower(level_lower, log_level_str(cat->loglevel));
638
639 vty_out(vty, " logging level %s %s%s", cat_lower, level_lower,
640 VTY_NEWLINE);
641 }
642
643 /* FIXME: levels */
644
645 return 1;
646}
647
648static int config_write_log(struct vty *vty)
649{
650 struct log_target *dbg = vty->index;
651
652 llist_for_each_entry(dbg, &osmo_log_target_list, entry)
653 config_write_log_single(vty, dbg);
654
655 return 1;
656}
657
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200658void logging_vty_add_cmds()
659{
660 install_element_ve(&enable_logging_cmd);
661 install_element_ve(&disable_logging_cmd);
662 install_element_ve(&logging_fltr_all_cmd);
663 install_element_ve(&logging_use_clr_cmd);
664 install_element_ve(&logging_prnt_timestamp_cmd);
665 install_element_ve(&logging_set_category_mask_cmd);
666 install_element_ve(&logging_level_cmd);
667 install_element_ve(&show_logging_vty_cmd);
Harald Welte28222962011-02-18 20:37:04 +0100668
669 install_node(&cfg_log_node, config_write_log);
670 install_element(CFG_LOG_NODE, &cfg_log_fltr_all_cmd);
671 install_element(CFG_LOG_NODE, &cfg_log_use_clr_cmd);
672 install_element(CFG_LOG_NODE, &cfg_log_timestamp_cmd);
673 install_element(CFG_LOG_NODE, &cfg_log_level_cmd);
674
675 install_element(CONFIG_NODE, &cfg_log_stderr_cmd);
676 install_element(CONFIG_NODE, &cfg_no_log_stderr_cmd);
677 install_element(CONFIG_NODE, &cfg_log_file_cmd);
678 install_element(CONFIG_NODE, &cfg_no_log_file_cmd);
679#ifdef HAVE_SYSLOG_H
680 install_element(CONFIG_NODE, &cfg_log_syslog_cmd);
681 install_element(CONFIG_NODE, &cfg_log_syslog_local_cmd);
682 install_element(CONFIG_NODE, &cfg_no_log_syslog_cmd);
683#endif
Harald Welte3fb0b6f2010-05-19 19:02:52 +0200684}