]> git.proxmox.com Git - mirror_frr.git/blame - lib/log_vty.c
lib: save instance number in zlog
[mirror_frr.git] / lib / log_vty.c
CommitLineData
f73126c3
SW
1/*
2 * Logging - VTY code
3 * Copyright (C) 2019 Cumulus Networks, Inc.
4 * Stephen Worley
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <zebra.h>
22
23#include "lib/log_vty.h"
24#include "command.h"
f73126c3 25#include "lib/log.h"
0bdeb5e5
DL
26#include "lib/zlog_targets.h"
27#include "lib/lib_errors.h"
28#include "lib/printfrr.h"
29
f73126c3
SW
30#ifndef VTYSH_EXTRACT_PL
31#include "lib/log_vty_clippy.c"
32#endif
33
0bdeb5e5
DL
34#define ZLOG_MAXLVL(a, b) MAX(a, b)
35
8451921b 36DEFINE_HOOK(zlog_rotate, (), ());
ba9256d2 37DEFINE_HOOK(zlog_cli_show, (struct vty * vty), (vty));
0bdeb5e5
DL
38
39static const int log_default_lvl = LOG_DEBUG;
40
41static int log_config_stdout_lvl = ZLOG_DISABLED;
42static int log_config_syslog_lvl = ZLOG_DISABLED;
43static int log_cmdline_stdout_lvl = ZLOG_DISABLED;
44static int log_cmdline_syslog_lvl = ZLOG_DISABLED;
45
46static struct zlog_cfg_file zt_file_cmdline = {
47 .prio_min = ZLOG_DISABLED,
48};
49static struct zlog_cfg_file zt_file = {
50 .prio_min = ZLOG_DISABLED,
51};
52static struct zlog_cfg_file zt_stdout = {
53 .prio_min = ZLOG_DISABLED,
54};
1c408628
DL
55static struct zlog_cfg_filterfile zt_filterfile = {
56 .parent = {
57 .prio_min = ZLOG_DISABLED,
58 },
59};
0bdeb5e5
DL
60
61static const char *zlog_progname;
62static const char *zlog_protoname;
63
64static const struct facility_map {
65 int facility;
66 const char *name;
67 size_t match;
68} syslog_facilities[] = {
69 {LOG_KERN, "kern", 1},
70 {LOG_USER, "user", 2},
71 {LOG_MAIL, "mail", 1},
72 {LOG_DAEMON, "daemon", 1},
73 {LOG_AUTH, "auth", 1},
74 {LOG_SYSLOG, "syslog", 1},
75 {LOG_LPR, "lpr", 2},
76 {LOG_NEWS, "news", 1},
77 {LOG_UUCP, "uucp", 2},
78 {LOG_CRON, "cron", 1},
79#ifdef LOG_FTP
80 {LOG_FTP, "ftp", 1},
81#endif
82 {LOG_LOCAL0, "local0", 6},
83 {LOG_LOCAL1, "local1", 6},
84 {LOG_LOCAL2, "local2", 6},
85 {LOG_LOCAL3, "local3", 6},
86 {LOG_LOCAL4, "local4", 6},
87 {LOG_LOCAL5, "local5", 6},
88 {LOG_LOCAL6, "local6", 6},
89 {LOG_LOCAL7, "local7", 6},
90 {0, NULL, 0},
91};
92
93static const char * const zlog_priority[] = {
94 "emergencies", "alerts", "critical", "errors", "warnings",
95 "notifications", "informational", "debugging", NULL,
96};
97
98static const char *facility_name(int facility)
99{
100 const struct facility_map *fm;
101
102 for (fm = syslog_facilities; fm->name; fm++)
103 if (fm->facility == facility)
104 return fm->name;
105 return "";
106}
107
108static int facility_match(const char *str)
f73126c3 109{
0bdeb5e5 110 const struct facility_map *fm;
f73126c3 111
0bdeb5e5
DL
112 for (fm = syslog_facilities; fm->name; fm++)
113 if (!strncmp(str, fm->name, fm->match))
114 return fm->facility;
115 return -1;
116}
117
118int log_level_match(const char *s)
119{
120 int level;
121
122 for (level = 0; zlog_priority[level] != NULL; level++)
123 if (!strncmp(s, zlog_priority[level], 2))
124 return level;
125 return ZLOG_DISABLED;
126}
127
128void zlog_rotate(void)
129{
130 zlog_file_rotate(&zt_file);
1c408628 131 zlog_file_rotate(&zt_filterfile.parent);
0bdeb5e5
DL
132 hook_call(zlog_rotate);
133}
134
135
136void log_show_syslog(struct vty *vty)
137{
138 int level = zlog_syslog_get_prio_min();
139
140 vty_out(vty, "Syslog logging: ");
141 if (level == ZLOG_DISABLED)
142 vty_out(vty, "disabled\n");
f73126c3 143 else
0bdeb5e5
DL
144 vty_out(vty, "level %s, facility %s, ident %s\n",
145 zlog_priority[level],
146 facility_name(zlog_syslog_get_facility()),
147 zlog_progname);
148}
f73126c3 149
48843422
DL
150DEFUN_NOSH (show_logging,
151 show_logging_cmd,
152 "show logging",
153 SHOW_STR
154 "Show current logging configuration\n")
0bdeb5e5
DL
155{
156 log_show_syslog(vty);
157
158 vty_out(vty, "Stdout logging: ");
159 if (zt_stdout.prio_min == ZLOG_DISABLED)
160 vty_out(vty, "disabled");
161 else
162 vty_out(vty, "level %s",
163 zlog_priority[zt_stdout.prio_min]);
164 vty_out(vty, "\n");
165
166 vty_out(vty, "File logging: ");
167 if (zt_file.prio_min == ZLOG_DISABLED || !zt_file.filename)
168 vty_out(vty, "disabled");
169 else
170 vty_out(vty, "level %s, filename %s",
171 zlog_priority[zt_file.prio_min], zt_file.filename);
172 vty_out(vty, "\n");
173
1c408628
DL
174 if (zt_filterfile.parent.prio_min != ZLOG_DISABLED
175 && zt_filterfile.parent.filename)
176 vty_out(vty, "Filtered-file logging: level %s, filename %s\n",
177 zlog_priority[zt_filterfile.parent.prio_min],
178 zt_filterfile.parent.filename);
179
0bdeb5e5
DL
180 if (log_cmdline_syslog_lvl != ZLOG_DISABLED)
181 vty_out(vty,
182 "From command line: \"--log syslog --log-level %s\"\n",
183 zlog_priority[log_cmdline_syslog_lvl]);
184 if (log_cmdline_stdout_lvl != ZLOG_DISABLED)
185 vty_out(vty,
186 "From command line: \"--log stdout --log-level %s\"\n",
187 zlog_priority[log_cmdline_stdout_lvl]);
188 if (zt_file_cmdline.prio_min != ZLOG_DISABLED)
189 vty_out(vty,
190 "From command line: \"--log file:%s --log-level %s\"\n",
191 zt_file_cmdline.filename,
192 zlog_priority[zt_file_cmdline.prio_min]);
193
194 vty_out(vty, "Protocol name: %s\n", zlog_protoname);
195 vty_out(vty, "Record priority: %s\n",
196 (zt_file.record_priority ? "enabled" : "disabled"));
197 vty_out(vty, "Timestamp precision: %d\n", zt_file.ts_subsec);
ba9256d2
DL
198
199 hook_call(zlog_cli_show, vty);
f73126c3
SW
200 return CMD_SUCCESS;
201}
202
0bdeb5e5
DL
203DEFPY (config_log_stdout,
204 config_log_stdout_cmd,
205 "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
206 "Logging control\n"
207 "Set stdout logging level\n"
208 LOG_LEVEL_DESC)
209{
210 int level;
211
212 if (levelarg) {
213 level = log_level_match(levelarg);
214 if (level == ZLOG_DISABLED)
215 return CMD_ERR_NO_MATCH;
216 } else
217 level = log_default_lvl;
218
219 log_config_stdout_lvl = level;
220 zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl,
221 log_cmdline_stdout_lvl);
222 zlog_file_set_other(&zt_stdout);
223 return CMD_SUCCESS;
224}
225
226DEFUN (no_config_log_stdout,
227 no_config_log_stdout_cmd,
228 "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
229 NO_STR
230 "Logging control\n"
231 "Cancel logging to stdout\n"
232 LOG_LEVEL_DESC)
f73126c3 233{
0bdeb5e5
DL
234 log_config_stdout_lvl = ZLOG_DISABLED;
235 zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl,
236 log_cmdline_stdout_lvl);
237 zlog_file_set_other(&zt_stdout);
f73126c3
SW
238 return CMD_SUCCESS;
239}
240
0bdeb5e5
DL
241DEFUN_HIDDEN (config_log_monitor,
242 config_log_monitor_cmd,
243 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
244 "Logging control\n"
245 "Set terminal line (monitor) logging level\n"
246 LOG_LEVEL_DESC)
247{
248 vty_out(vty, "%% \"log monitor\" is deprecated and does nothing.\n");
249 return CMD_SUCCESS;
250}
251
252DEFUN_HIDDEN (no_config_log_monitor,
253 no_config_log_monitor_cmd,
254 "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
255 NO_STR
256 "Logging control\n"
257 "Disable terminal line (monitor) logging\n"
258 LOG_LEVEL_DESC)
259{
260 return CMD_SUCCESS;
261}
262
263static int set_log_file(struct zlog_cfg_file *target, struct vty *vty,
264 const char *fname, int loglevel)
265{
fc746f1c 266 char path[MAXPATHLEN + 1];
0bdeb5e5
DL
267 const char *fullpath;
268 bool ok;
269
fc746f1c 270
0bdeb5e5
DL
271 /* Path detection. */
272 if (!IS_DIRECTORY_SEP(*fname)) {
273 char cwd[MAXPATHLEN + 1];
274
275 cwd[MAXPATHLEN] = '\0';
276
277 if (getcwd(cwd, MAXPATHLEN) == NULL) {
278 flog_err_sys(EC_LIB_SYSTEM_CALL,
279 "config_log_file: Unable to alloc mem!");
280 return CMD_WARNING_CONFIG_FAILED;
281 }
282
08808541
QY
283 int pr = snprintf(path, sizeof(path), "%s/%s", cwd, fname);
284 if (pr < 0 || (unsigned int)pr >= sizeof(path)) {
285 flog_err_sys(
286 EC_LIB_SYSTEM_CALL,
287 "%s: Path too long ('%s/%s'); system maximum is %u",
288 __func__, cwd, fname, MAXPATHLEN);
289 return CMD_WARNING_CONFIG_FAILED;
290 }
291
fc746f1c 292 fullpath = path;
0bdeb5e5
DL
293 } else
294 fullpath = fname;
295
296 target->prio_min = loglevel;
297 ok = zlog_file_set_filename(target, fullpath);
298
0bdeb5e5
DL
299 if (!ok) {
300 if (vty)
301 vty_out(vty, "can't open logfile %s\n", fname);
302 return CMD_WARNING_CONFIG_FAILED;
303 }
304 return CMD_SUCCESS;
305}
306
307void command_setup_early_logging(const char *dest, const char *level)
308{
309 int nlevel;
310 char *sep;
311 int len;
312 char type[8];
313
314 if (level) {
315 nlevel = log_level_match(level);
316
317 if (nlevel == ZLOG_DISABLED) {
318 fprintf(stderr, "invalid log level \"%s\"\n", level);
319 exit(1);
320 }
321 } else
322 nlevel = log_default_lvl;
323
324 if (!dest)
325 return;
326
327 sep = strchr(dest, ':');
328 len = sep ? (int)(sep - dest) : (int)strlen(dest);
329
330 snprintfrr(type, sizeof(type), "%.*s", len, dest);
331
332 if (strcmp(type, "stdout") == 0) {
333 log_cmdline_stdout_lvl = nlevel;
334 zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl,
335 log_cmdline_stdout_lvl);
336 zlog_file_set_other(&zt_stdout);
337 return;
338 }
339 if (strcmp(type, "syslog") == 0) {
340 log_cmdline_syslog_lvl = nlevel;
341 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
342 log_cmdline_syslog_lvl));
343 return;
344 }
345 if (strcmp(type, "file") == 0 && sep) {
346 sep++;
347 set_log_file(&zt_file_cmdline, NULL, sep, nlevel);
348 return;
349 }
350
351 fprintf(stderr, "invalid log target \"%s\" (\"%s\")\n", type, dest);
352 exit(1);
353}
354
355DEFUN (clear_log_cmdline,
356 clear_log_cmdline_cmd,
357 "clear log cmdline-targets",
358 CLEAR_STR
359 "Logging control\n"
360 "Disable log targets specified at startup by --log option\n")
f73126c3 361{
0bdeb5e5
DL
362 zt_file_cmdline.prio_min = ZLOG_DISABLED;
363 zlog_file_set_other(&zt_file_cmdline);
364
365 log_cmdline_syslog_lvl = ZLOG_DISABLED;
366 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
367 log_cmdline_syslog_lvl));
368
369 log_cmdline_stdout_lvl = ZLOG_DISABLED;
370 zt_stdout.prio_min = ZLOG_MAXLVL(log_config_stdout_lvl,
371 log_cmdline_stdout_lvl);
372 zlog_file_set_other(&zt_stdout);
f73126c3 373
0bdeb5e5
DL
374 return CMD_SUCCESS;
375}
f73126c3 376
0bdeb5e5
DL
377DEFPY (config_log_file,
378 config_log_file_cmd,
379 "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
380 "Logging control\n"
381 "Logging to file\n"
382 "Logging filename\n"
383 LOG_LEVEL_DESC)
384{
385 int level = log_default_lvl;
386
387 if (levelarg) {
388 level = log_level_match(levelarg);
389 if (level == ZLOG_DISABLED)
390 return CMD_ERR_NO_MATCH;
f73126c3 391 }
0bdeb5e5
DL
392 return set_log_file(&zt_file, vty, filename, level);
393}
394
395DEFUN (no_config_log_file,
396 no_config_log_file_cmd,
397 "no log file [FILENAME [LEVEL]]",
398 NO_STR
399 "Logging control\n"
400 "Cancel logging to file\n"
401 "Logging file name\n"
402 "Logging level\n")
403{
404 zt_file.prio_min = ZLOG_DISABLED;
405 zlog_file_set_other(&zt_file);
406 return CMD_SUCCESS;
407}
408
409DEFPY (config_log_syslog,
410 config_log_syslog_cmd,
411 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
412 "Logging control\n"
413 "Set syslog logging level\n"
414 LOG_LEVEL_DESC)
415{
416 int level;
417
418 if (levelarg) {
419 level = log_level_match(levelarg);
420
421 if (level == ZLOG_DISABLED)
422 return CMD_ERR_NO_MATCH;
423 } else
424 level = log_default_lvl;
425
426 log_config_syslog_lvl = level;
427 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
428 log_cmdline_syslog_lvl));
429 return CMD_SUCCESS;
430}
431
432DEFUN (no_config_log_syslog,
433 no_config_log_syslog_cmd,
434 "no log syslog [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>] [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
435 NO_STR
436 "Logging control\n"
437 "Cancel logging to syslog\n"
438 LOG_FACILITY_DESC
439 LOG_LEVEL_DESC)
440{
441 log_config_syslog_lvl = ZLOG_DISABLED;
442 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
443 log_cmdline_syslog_lvl));
444 return CMD_SUCCESS;
445}
446
447DEFPY (config_log_facility,
448 config_log_facility_cmd,
449 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>$facilityarg",
450 "Logging control\n"
451 "Facility parameter for syslog messages\n"
452 LOG_FACILITY_DESC)
453{
454 int facility = facility_match(facilityarg);
455
456 zlog_syslog_set_facility(facility);
457 return CMD_SUCCESS;
458}
459
460DEFUN (no_config_log_facility,
461 no_config_log_facility_cmd,
462 "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
463 NO_STR
464 "Logging control\n"
465 "Reset syslog facility to default (daemon)\n"
466 LOG_FACILITY_DESC)
467{
468 zlog_syslog_set_facility(LOG_DAEMON);
469 return CMD_SUCCESS;
470}
471
472DEFUN (config_log_record_priority,
473 config_log_record_priority_cmd,
474 "log record-priority",
475 "Logging control\n"
476 "Log the priority of the message within the message\n")
477{
478 zt_file.record_priority = true;
479 zlog_file_set_other(&zt_file);
480 zt_stdout.record_priority = true;
481 zlog_file_set_other(&zt_stdout);
1c408628
DL
482 zt_filterfile.parent.record_priority = true;
483 zlog_file_set_other(&zt_filterfile.parent);
0bdeb5e5
DL
484 return CMD_SUCCESS;
485}
486
487DEFUN (no_config_log_record_priority,
488 no_config_log_record_priority_cmd,
489 "no log record-priority",
490 NO_STR
491 "Logging control\n"
492 "Do not log the priority of the message within the message\n")
493{
494 zt_file.record_priority = false;
495 zlog_file_set_other(&zt_file);
496 zt_stdout.record_priority = false;
497 zlog_file_set_other(&zt_stdout);
1c408628
DL
498 zt_filterfile.parent.record_priority = false;
499 zlog_file_set_other(&zt_filterfile.parent);
0bdeb5e5
DL
500 return CMD_SUCCESS;
501}
f73126c3 502
0bdeb5e5
DL
503DEFPY (config_log_timestamp_precision,
504 config_log_timestamp_precision_cmd,
505 "log timestamp precision (0-6)",
506 "Logging control\n"
507 "Timestamp configuration\n"
508 "Set the timestamp precision\n"
509 "Number of subsecond digits\n")
510{
511 zt_file.ts_subsec = precision;
512 zlog_file_set_other(&zt_file);
513 zt_stdout.ts_subsec = precision;
514 zlog_file_set_other(&zt_stdout);
1c408628
DL
515 zt_filterfile.parent.ts_subsec = precision;
516 zlog_file_set_other(&zt_filterfile.parent);
0bdeb5e5
DL
517 return CMD_SUCCESS;
518}
f73126c3 519
0bdeb5e5
DL
520DEFUN (no_config_log_timestamp_precision,
521 no_config_log_timestamp_precision_cmd,
522 "no log timestamp precision [(0-6)]",
523 NO_STR
524 "Logging control\n"
525 "Timestamp configuration\n"
526 "Reset the timestamp precision to the default value of 0\n"
527 "Number of subsecond digits\n")
528{
529 zt_file.ts_subsec = 0;
530 zlog_file_set_other(&zt_file);
531 zt_stdout.ts_subsec = 0;
532 zlog_file_set_other(&zt_stdout);
1c408628
DL
533 zt_filterfile.parent.ts_subsec = 0;
534 zlog_file_set_other(&zt_filterfile.parent);
535 return CMD_SUCCESS;
536}
537
a3c67498
DL
538DEFPY (config_log_ec,
539 config_log_ec_cmd,
540 "[no] log error-category",
541 NO_STR
542 "Logging control\n"
543 "Prefix log message text with [EC 9999] code\n")
544{
545 zlog_set_prefix_ec(!no);
546 return CMD_SUCCESS;
547}
548
549DEFPY (config_log_xid,
550 config_log_xid_cmd,
551 "[no] log unique-id",
552 NO_STR
553 "Logging control\n"
554 "Prefix log message text with [XXXXX-XXXXX] identifier\n")
555{
556 zlog_set_prefix_xid(!no);
557 return CMD_SUCCESS;
558}
559
1c408628
DL
560DEFPY (config_log_filterfile,
561 config_log_filterfile_cmd,
562 "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
563 "Logging control\n"
564 "Logging to file with string filter\n"
565 "Logging filename\n"
566 LOG_LEVEL_DESC)
567{
568 int level = log_default_lvl;
569
570 if (levelarg) {
571 level = log_level_match(levelarg);
572 if (level == ZLOG_DISABLED)
573 return CMD_ERR_NO_MATCH;
574 }
575 return set_log_file(&zt_filterfile.parent, vty, filename, level);
576}
577
578DEFUN (no_config_log_filterfile,
579 no_config_log_filterfile_cmd,
580 "no log filtered-file [FILENAME [LEVEL]]",
581 NO_STR
582 "Logging control\n"
583 "Cancel logging to file with string filter\n"
584 "Logging file name\n"
585 "Logging level\n")
586{
587 zt_filterfile.parent.prio_min = ZLOG_DISABLED;
588 zlog_file_set_other(&zt_filterfile.parent);
589 return CMD_SUCCESS;
590}
591
592DEFPY (log_filter,
593 log_filter_cmd,
9c2aa919 594 "[no] log filter-text WORD$filter",
1c408628 595 NO_STR
9c2aa919 596 "Logging control\n"
1c408628
DL
597 FILTER_LOG_STR
598 "String to filter by\n")
599{
600 int ret = 0;
601
602 if (no)
603 ret = zlog_filter_del(filter);
604 else
605 ret = zlog_filter_add(filter);
606
607 if (ret == 1) {
608 vty_out(vty, "%% filter table full\n");
609 return CMD_WARNING;
610 } else if (ret != 0) {
611 vty_out(vty, "%% failed to %s log filter\n",
612 (no ? "remove" : "apply"));
613 return CMD_WARNING;
614 }
615
616 vty_out(vty, " %s\n", filter);
617 return CMD_SUCCESS;
618}
619
620/* Clear all log filters */
621DEFPY (log_filter_clear,
622 log_filter_clear_cmd,
9c2aa919 623 "clear log filter-text",
1c408628 624 CLEAR_STR
9c2aa919 625 "Logging control\n"
1c408628
DL
626 FILTER_LOG_STR)
627{
628 zlog_filter_clear();
629 return CMD_SUCCESS;
630}
631
632/* Show log filter */
633DEFPY (show_log_filter,
634 show_log_filter_cmd,
9c2aa919 635 "show logging filter-text",
1c408628 636 SHOW_STR
9c2aa919 637 "Show current logging configuration\n"
1c408628
DL
638 FILTER_LOG_STR)
639{
640 char log_filters[ZLOG_FILTERS_MAX * (ZLOG_FILTER_LENGTH_MAX + 3)] = "";
641 int len = 0;
642
643 len = zlog_filter_dump(log_filters, sizeof(log_filters));
644
645 if (len == -1) {
646 vty_out(vty, "%% failed to get filters\n");
647 return CMD_WARNING;
648 }
649
650 if (len != 0)
651 vty_out(vty, "%s", log_filters);
652
f73126c3
SW
653 return CMD_SUCCESS;
654}
655
7c945dff
MS
656/* Enable/disable 'immediate' mode, with no output buffering */
657DEFPY (log_immediate_mode,
658 log_immediate_mode_cmd,
659 "[no] log immediate-mode",
660 NO_STR
661 "Logging control"
662 "Output immediately, without buffering")
663{
664 zlog_set_immediate(!no);
665 return CMD_SUCCESS;
666}
667
0bdeb5e5 668void log_config_write(struct vty *vty)
f73126c3 669{
0bdeb5e5
DL
670 bool show_cmdline_hint = false;
671
672 if (zt_file.prio_min != ZLOG_DISABLED && zt_file.filename) {
673 vty_out(vty, "log file %s", zt_file.filename);
674
675 if (zt_file.prio_min != log_default_lvl)
676 vty_out(vty, " %s", zlog_priority[zt_file.prio_min]);
677 vty_out(vty, "\n");
678 }
679
1c408628
DL
680 if (zt_filterfile.parent.prio_min != ZLOG_DISABLED
681 && zt_filterfile.parent.filename) {
682 vty_out(vty, "log filtered-file %s",
683 zt_filterfile.parent.filename);
684
685 if (zt_filterfile.parent.prio_min != log_default_lvl)
686 vty_out(vty, " %s",
687 zlog_priority[zt_filterfile.parent.prio_min]);
688 vty_out(vty, "\n");
689 }
690
0bdeb5e5
DL
691 if (log_config_stdout_lvl != ZLOG_DISABLED) {
692 vty_out(vty, "log stdout");
693
694 if (log_config_stdout_lvl != log_default_lvl)
695 vty_out(vty, " %s",
696 zlog_priority[log_config_stdout_lvl]);
697 vty_out(vty, "\n");
698 }
699
700 if (log_config_syslog_lvl != ZLOG_DISABLED) {
701 vty_out(vty, "log syslog");
702
703 if (log_config_syslog_lvl != log_default_lvl)
704 vty_out(vty, " %s",
705 zlog_priority[log_config_syslog_lvl]);
706 vty_out(vty, "\n");
707 }
708
709 if (log_cmdline_syslog_lvl != ZLOG_DISABLED) {
710 vty_out(vty,
711 "! \"log syslog %s\" enabled by \"--log\" startup option\n",
712 zlog_priority[log_cmdline_syslog_lvl]);
713 show_cmdline_hint = true;
714 }
715 if (log_cmdline_stdout_lvl != ZLOG_DISABLED) {
716 vty_out(vty,
717 "! \"log stdout %s\" enabled by \"--log\" startup option\n",
718 zlog_priority[log_cmdline_stdout_lvl]);
719 show_cmdline_hint = true;
720 }
721 if (zt_file_cmdline.prio_min != ZLOG_DISABLED) {
722 vty_out(vty,
723 "! \"log file %s %s\" enabled by \"--log\" startup option\n",
724 zt_file_cmdline.filename,
725 zlog_priority[zt_file_cmdline.prio_min]);
726 show_cmdline_hint = true;
727 }
728 if (show_cmdline_hint)
729 vty_out(vty,
730 "! use \"clear log cmdline-targets\" to remove this target\n");
731
732 if (zlog_syslog_get_facility() != LOG_DAEMON)
733 vty_out(vty, "log facility %s\n",
734 facility_name(zlog_syslog_get_facility()));
735
736 if (zt_file.record_priority == 1)
737 vty_out(vty, "log record-priority\n");
738
739 if (zt_file.ts_subsec > 0)
740 vty_out(vty, "log timestamp precision %d\n",
741 zt_file.ts_subsec);
a3c67498
DL
742
743 if (!zlog_get_prefix_ec())
744 vty_out(vty, "no log error-category\n");
745 if (!zlog_get_prefix_xid())
746 vty_out(vty, "no log unique-id\n");
0bdeb5e5
DL
747}
748
749static int log_vty_init(const char *progname, const char *protoname,
750 unsigned short instance, uid_t uid, gid_t gid)
751{
752 zlog_progname = progname;
753 zlog_protoname = protoname;
754
a3c67498
DL
755 zlog_set_prefix_ec(true);
756 zlog_set_prefix_xid(true);
757
1c408628
DL
758 zlog_filterfile_init(&zt_filterfile);
759
0bdeb5e5
DL
760 zlog_file_set_fd(&zt_stdout, STDOUT_FILENO);
761 return 0;
762}
763
764__attribute__((_CONSTRUCTOR(475))) static void log_vty_preinit(void)
765{
766 hook_register(zlog_init, log_vty_init);
767}
768
769void log_cmd_init(void)
770{
771 install_element(VIEW_NODE, &show_logging_cmd);
772 install_element(ENABLE_NODE, &clear_log_cmdline_cmd);
773
774 install_element(CONFIG_NODE, &config_log_stdout_cmd);
775 install_element(CONFIG_NODE, &no_config_log_stdout_cmd);
776 install_element(CONFIG_NODE, &config_log_monitor_cmd);
777 install_element(CONFIG_NODE, &no_config_log_monitor_cmd);
778 install_element(CONFIG_NODE, &config_log_file_cmd);
779 install_element(CONFIG_NODE, &no_config_log_file_cmd);
780 install_element(CONFIG_NODE, &config_log_syslog_cmd);
781 install_element(CONFIG_NODE, &no_config_log_syslog_cmd);
782 install_element(CONFIG_NODE, &config_log_facility_cmd);
783 install_element(CONFIG_NODE, &no_config_log_facility_cmd);
784 install_element(CONFIG_NODE, &config_log_record_priority_cmd);
785 install_element(CONFIG_NODE, &no_config_log_record_priority_cmd);
786 install_element(CONFIG_NODE, &config_log_timestamp_precision_cmd);
787 install_element(CONFIG_NODE, &no_config_log_timestamp_precision_cmd);
a3c67498
DL
788 install_element(CONFIG_NODE, &config_log_ec_cmd);
789 install_element(CONFIG_NODE, &config_log_xid_cmd);
1c408628
DL
790
791 install_element(VIEW_NODE, &show_log_filter_cmd);
792 install_element(CONFIG_NODE, &log_filter_cmd);
793 install_element(CONFIG_NODE, &log_filter_clear_cmd);
794 install_element(CONFIG_NODE, &config_log_filterfile_cmd);
795 install_element(CONFIG_NODE, &no_config_log_filterfile_cmd);
7c945dff 796 install_element(CONFIG_NODE, &log_immediate_mode_cmd);
f73126c3 797}