3 * Copyright (C) 2019 Cumulus Networks, Inc.
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)
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
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
23 #include "lib/log_vty.h"
26 #include "lib/zlog_targets.h"
27 #include "lib/zlog_5424.h"
28 #include "lib/lib_errors.h"
29 #include "lib/printfrr.h"
30 #include "lib/systemd.h"
32 #ifndef VTYSH_EXTRACT_PL
33 #include "lib/log_vty_clippy.c"
36 #define ZLOG_MAXLVL(a, b) MAX(a, b)
38 DEFINE_HOOK(zlog_rotate
, (), ());
39 DEFINE_HOOK(zlog_cli_show
, (struct vty
* vty
), (vty
));
41 static unsigned logmsgs_with_persist_bt
;
43 static const int log_default_lvl
= LOG_DEBUG
;
45 static int log_config_stdout_lvl
= ZLOG_DISABLED
;
46 static int log_config_syslog_lvl
= ZLOG_DISABLED
;
47 static int log_cmdline_stdout_lvl
= ZLOG_DISABLED
;
48 static int log_cmdline_syslog_lvl
= ZLOG_DISABLED
;
50 static struct zlog_cfg_file zt_file_cmdline
= {
51 .prio_min
= ZLOG_DISABLED
,
53 static struct zlog_cfg_file zt_file
= {
54 .prio_min
= ZLOG_DISABLED
,
56 static struct zlog_cfg_filterfile zt_filterfile
= {
58 .prio_min
= ZLOG_DISABLED
,
62 static struct zlog_cfg_file zt_stdout_file
= {
63 .prio_min
= ZLOG_DISABLED
,
65 static struct zlog_cfg_5424 zt_stdout_journald
= {
66 .prio_min
= ZLOG_DISABLED
,
68 .fmt
= ZLOG_FMT_JOURNALD
,
69 .dst
= ZLOG_5424_DST_UNIX
,
70 .filename
= "/run/systemd/journal/socket",
72 /* this can't be changed through config since this target substitutes
73 * in for the "plain" stdout target
75 .facility
= LOG_DAEMON
,
82 static bool stdout_journald_in_use
;
84 const char *zlog_progname
;
85 static const char *zlog_protoname
;
87 static const struct facility_map
{
91 } syslog_facilities
[] = {
92 {LOG_KERN
, "kern", 1},
93 {LOG_USER
, "user", 2},
94 {LOG_MAIL
, "mail", 1},
95 {LOG_DAEMON
, "daemon", 1},
96 {LOG_AUTH
, "auth", 1},
97 {LOG_SYSLOG
, "syslog", 1},
99 {LOG_NEWS
, "news", 1},
100 {LOG_UUCP
, "uucp", 2},
101 {LOG_CRON
, "cron", 1},
105 {LOG_LOCAL0
, "local0", 6},
106 {LOG_LOCAL1
, "local1", 6},
107 {LOG_LOCAL2
, "local2", 6},
108 {LOG_LOCAL3
, "local3", 6},
109 {LOG_LOCAL4
, "local4", 6},
110 {LOG_LOCAL5
, "local5", 6},
111 {LOG_LOCAL6
, "local6", 6},
112 {LOG_LOCAL7
, "local7", 6},
116 static const char * const zlog_priority
[] = {
117 "emergencies", "alerts", "critical", "errors", "warnings",
118 "notifications", "informational", "debugging", NULL
,
121 const char *zlog_priority_str(int priority
)
123 if (priority
> LOG_DEBUG
)
125 return zlog_priority
[priority
];
128 const char *facility_name(int facility
)
130 const struct facility_map
*fm
;
132 for (fm
= syslog_facilities
; fm
->name
; fm
++)
133 if (fm
->facility
== facility
)
138 int facility_match(const char *str
)
140 const struct facility_map
*fm
;
142 for (fm
= syslog_facilities
; fm
->name
; fm
++)
143 if (!strncmp(str
, fm
->name
, fm
->match
))
148 int log_level_match(const char *s
)
152 for (level
= 0; zlog_priority
[level
] != NULL
; level
++)
153 if (!strncmp(s
, zlog_priority
[level
], 2))
155 return ZLOG_DISABLED
;
158 void zlog_rotate(void)
160 zlog_file_rotate(&zt_file
);
161 zlog_file_rotate(&zt_filterfile
.parent
);
162 zlog_file_rotate(&zt_file_cmdline
);
163 hook_call(zlog_rotate
);
167 void log_show_syslog(struct vty
*vty
)
169 int level
= zlog_syslog_get_prio_min();
171 vty_out(vty
, "Syslog logging: ");
172 if (level
== ZLOG_DISABLED
)
173 vty_out(vty
, "disabled\n");
175 vty_out(vty
, "level %s, facility %s, ident %s\n",
176 zlog_priority
[level
],
177 facility_name(zlog_syslog_get_facility()),
181 DEFUN_NOSH (show_logging
,
185 "Show current logging configuration\n")
189 log_show_syslog(vty
);
191 stdout_prio
= stdout_journald_in_use
? zt_stdout_journald
.prio_min
192 : zt_stdout_file
.prio_min
;
194 vty_out(vty
, "Stdout logging: ");
195 if (stdout_prio
== ZLOG_DISABLED
)
196 vty_out(vty
, "disabled");
198 vty_out(vty
, "level %s", zlog_priority
[stdout_prio
]);
201 vty_out(vty
, "File logging: ");
202 if (zt_file
.prio_min
== ZLOG_DISABLED
|| !zt_file
.filename
)
203 vty_out(vty
, "disabled");
205 vty_out(vty
, "level %s, filename %s",
206 zlog_priority
[zt_file
.prio_min
], zt_file
.filename
);
209 if (zt_filterfile
.parent
.prio_min
!= ZLOG_DISABLED
210 && zt_filterfile
.parent
.filename
)
211 vty_out(vty
, "Filtered-file logging: level %s, filename %s\n",
212 zlog_priority
[zt_filterfile
.parent
.prio_min
],
213 zt_filterfile
.parent
.filename
);
215 if (log_cmdline_syslog_lvl
!= ZLOG_DISABLED
)
217 "From command line: \"--log syslog --log-level %s\"\n",
218 zlog_priority
[log_cmdline_syslog_lvl
]);
219 if (log_cmdline_stdout_lvl
!= ZLOG_DISABLED
)
221 "From command line: \"--log stdout --log-level %s\"\n",
222 zlog_priority
[log_cmdline_stdout_lvl
]);
223 if (zt_file_cmdline
.prio_min
!= ZLOG_DISABLED
)
225 "From command line: \"--log file:%s --log-level %s\"\n",
226 zt_file_cmdline
.filename
,
227 zlog_priority
[zt_file_cmdline
.prio_min
]);
229 vty_out(vty
, "Protocol name: %s\n", zlog_protoname
);
230 vty_out(vty
, "Record priority: %s\n",
231 (zt_file
.record_priority
? "enabled" : "disabled"));
232 vty_out(vty
, "Timestamp precision: %d\n", zt_file
.ts_subsec
);
234 hook_call(zlog_cli_show
, vty
);
238 static void log_stdout_apply_level(void)
242 maxlvl
= ZLOG_MAXLVL(log_config_stdout_lvl
, log_cmdline_stdout_lvl
);
244 if (stdout_journald_in_use
) {
245 zt_stdout_journald
.prio_min
= maxlvl
;
246 zlog_5424_apply_meta(&zt_stdout_journald
);
248 zt_stdout_file
.prio_min
= maxlvl
;
249 zlog_file_set_other(&zt_stdout_file
);
253 DEFPY (config_log_stdout
,
254 config_log_stdout_cmd
,
255 "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
257 "Set stdout logging level\n"
263 level
= log_level_match(levelarg
);
264 if (level
== ZLOG_DISABLED
)
265 return CMD_ERR_NO_MATCH
;
267 level
= log_default_lvl
;
269 log_config_stdout_lvl
= level
;
270 log_stdout_apply_level();
274 DEFUN (no_config_log_stdout
,
275 no_config_log_stdout_cmd
,
276 "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
279 "Cancel logging to stdout\n"
282 log_config_stdout_lvl
= ZLOG_DISABLED
;
283 log_stdout_apply_level();
287 DEFUN_HIDDEN (config_log_monitor
,
288 config_log_monitor_cmd
,
289 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
291 "Set terminal line (monitor) logging level\n"
294 vty_out(vty
, "%% \"log monitor\" is deprecated and does nothing.\n");
298 DEFUN_HIDDEN (no_config_log_monitor
,
299 no_config_log_monitor_cmd
,
300 "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
303 "Disable terminal line (monitor) logging\n"
309 DEFPY_NOSH (debug_uid_backtrace
,
310 debug_uid_backtrace_cmd
,
311 "[no] debug unique-id UID backtrace",
314 "Options per individual log message, by unique ID\n"
315 "Log message unique ID (XXXXX-XXXXX)\n"
316 "Add backtrace to log when message is printed\n")
318 struct xrefdata search
, *xrd
;
319 struct xrefdata_logmsg
*xrdl
;
322 strlcpy(search
.uid
, uid
, sizeof(search
.uid
));
323 xrd
= xrefdata_uid_find(&xrefdata_uid
, &search
);
326 return CMD_ERR_NOTHING_TODO
;
328 if (xrd
->xref
->type
!= XREFT_LOGMSG
) {
329 vty_out(vty
, "%% ID \"%s\" is not a log message\n", uid
);
332 xrdl
= container_of(xrd
, struct xrefdata_logmsg
, xrefdata
);
334 flag
= (vty
->node
== CONFIG_NODE
) ? LOGMSG_FLAG_PERSISTENT
335 : LOGMSG_FLAG_EPHEMERAL
;
337 if ((xrdl
->fl_print_bt
& flag
) == (no
? 0 : flag
))
339 if (flag
== LOGMSG_FLAG_PERSISTENT
)
340 logmsgs_with_persist_bt
+= no
? -1 : 1;
342 xrdl
->fl_print_bt
^= flag
;
346 static int set_log_file(struct zlog_cfg_file
*target
, struct vty
*vty
,
347 const char *fname
, int loglevel
)
349 char path
[MAXPATHLEN
+ 1];
350 const char *fullpath
;
354 /* Path detection. */
355 if (!IS_DIRECTORY_SEP(*fname
)) {
356 char cwd
[MAXPATHLEN
+ 1];
358 cwd
[MAXPATHLEN
] = '\0';
360 if (getcwd(cwd
, MAXPATHLEN
) == NULL
) {
361 flog_err_sys(EC_LIB_SYSTEM_CALL
,
362 "config_log_file: Unable to alloc mem!");
363 return CMD_WARNING_CONFIG_FAILED
;
366 int pr
= snprintf(path
, sizeof(path
), "%s/%s", cwd
, fname
);
367 if (pr
< 0 || (unsigned int)pr
>= sizeof(path
)) {
370 "%s: Path too long ('%s/%s'); system maximum is %u",
371 __func__
, cwd
, fname
, MAXPATHLEN
);
372 return CMD_WARNING_CONFIG_FAILED
;
379 target
->prio_min
= loglevel
;
380 ok
= zlog_file_set_filename(target
, fullpath
);
384 vty_out(vty
, "can't open logfile %s\n", fname
);
385 return CMD_WARNING_CONFIG_FAILED
;
390 void command_setup_early_logging(const char *dest
, const char *level
)
398 nlevel
= log_level_match(level
);
400 if (nlevel
== ZLOG_DISABLED
) {
401 fprintf(stderr
, "invalid log level \"%s\"\n", level
);
405 nlevel
= log_default_lvl
;
410 sep
= strchr(dest
, ':');
411 len
= sep
? (int)(sep
- dest
) : (int)strlen(dest
);
413 snprintfrr(type
, sizeof(type
), "%.*s", len
, dest
);
415 if (strcmp(type
, "stdout") == 0) {
416 log_cmdline_stdout_lvl
= nlevel
;
417 log_stdout_apply_level();
420 if (strcmp(type
, "syslog") == 0) {
421 log_cmdline_syslog_lvl
= nlevel
;
422 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
423 log_cmdline_syslog_lvl
));
426 if (strcmp(type
, "file") == 0 && sep
) {
428 set_log_file(&zt_file_cmdline
, NULL
, sep
, nlevel
);
431 if (strcmp(type
, "monitor") == 0 && sep
) {
432 struct zlog_live_cfg cfg
= {};
437 fd
= strtoul(sep
, &endp
, 10);
438 if (!*sep
|| *endp
) {
439 fprintf(stderr
, "invalid monitor fd \"%s\"\n", sep
);
443 zlog_live_open_fd(&cfg
, nlevel
, fd
);
444 zlog_live_disown(&cfg
);
448 fprintf(stderr
, "invalid log target \"%s\" (\"%s\")\n", type
, dest
);
452 DEFUN (clear_log_cmdline
,
453 clear_log_cmdline_cmd
,
454 "clear log cmdline-targets",
457 "Disable log targets specified at startup by --log option\n")
459 zt_file_cmdline
.prio_min
= ZLOG_DISABLED
;
460 zlog_file_set_other(&zt_file_cmdline
);
462 log_cmdline_syslog_lvl
= ZLOG_DISABLED
;
463 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
464 log_cmdline_syslog_lvl
));
466 log_cmdline_stdout_lvl
= ZLOG_DISABLED
;
467 log_stdout_apply_level();
472 DEFPY (config_log_file
,
474 "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
480 int level
= log_default_lvl
;
483 level
= log_level_match(levelarg
);
484 if (level
== ZLOG_DISABLED
)
485 return CMD_ERR_NO_MATCH
;
487 return set_log_file(&zt_file
, vty
, filename
, level
);
490 DEFUN (no_config_log_file
,
491 no_config_log_file_cmd
,
492 "no log file [FILENAME [LEVEL]]",
495 "Cancel logging to file\n"
496 "Logging file name\n"
499 zt_file
.prio_min
= ZLOG_DISABLED
;
500 zlog_file_set_other(&zt_file
);
504 DEFPY (config_log_syslog
,
505 config_log_syslog_cmd
,
506 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
508 "Set syslog logging level\n"
514 level
= log_level_match(levelarg
);
516 if (level
== ZLOG_DISABLED
)
517 return CMD_ERR_NO_MATCH
;
519 level
= log_default_lvl
;
521 log_config_syslog_lvl
= level
;
522 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
523 log_cmdline_syslog_lvl
));
527 DEFUN (no_config_log_syslog
,
528 no_config_log_syslog_cmd
,
529 "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>]",
532 "Cancel logging to syslog\n"
536 log_config_syslog_lvl
= ZLOG_DISABLED
;
537 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
538 log_cmdline_syslog_lvl
));
542 DEFPY (config_log_facility
,
543 config_log_facility_cmd
,
544 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>$facilityarg",
546 "Facility parameter for syslog messages\n"
549 int facility
= facility_match(facilityarg
);
551 zlog_syslog_set_facility(facility
);
555 DEFUN (no_config_log_facility
,
556 no_config_log_facility_cmd
,
557 "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
560 "Reset syslog facility to default (daemon)\n"
563 zlog_syslog_set_facility(LOG_DAEMON
);
567 DEFUN (config_log_record_priority
,
568 config_log_record_priority_cmd
,
569 "log record-priority",
571 "Log the priority of the message within the message\n")
573 zt_file
.record_priority
= true;
574 zlog_file_set_other(&zt_file
);
575 if (!stdout_journald_in_use
) {
576 zt_stdout_file
.record_priority
= true;
577 zlog_file_set_other(&zt_stdout_file
);
579 zt_filterfile
.parent
.record_priority
= true;
580 zlog_file_set_other(&zt_filterfile
.parent
);
584 DEFUN (no_config_log_record_priority
,
585 no_config_log_record_priority_cmd
,
586 "no log record-priority",
589 "Do not log the priority of the message within the message\n")
591 zt_file
.record_priority
= false;
592 zlog_file_set_other(&zt_file
);
593 if (!stdout_journald_in_use
) {
594 zt_stdout_file
.record_priority
= false;
595 zlog_file_set_other(&zt_stdout_file
);
597 zt_filterfile
.parent
.record_priority
= false;
598 zlog_file_set_other(&zt_filterfile
.parent
);
602 DEFPY (config_log_timestamp_precision
,
603 config_log_timestamp_precision_cmd
,
604 "log timestamp precision (0-6)",
606 "Timestamp configuration\n"
607 "Set the timestamp precision\n"
608 "Number of subsecond digits\n")
610 zt_file
.ts_subsec
= precision
;
611 zlog_file_set_other(&zt_file
);
612 if (!stdout_journald_in_use
) {
613 zt_stdout_file
.ts_subsec
= precision
;
614 zlog_file_set_other(&zt_stdout_file
);
616 zt_filterfile
.parent
.ts_subsec
= precision
;
617 zlog_file_set_other(&zt_filterfile
.parent
);
621 DEFUN (no_config_log_timestamp_precision
,
622 no_config_log_timestamp_precision_cmd
,
623 "no log timestamp precision [(0-6)]",
626 "Timestamp configuration\n"
627 "Reset the timestamp precision to the default value of 0\n"
628 "Number of subsecond digits\n")
630 zt_file
.ts_subsec
= 0;
631 zlog_file_set_other(&zt_file
);
632 if (!stdout_journald_in_use
) {
633 zt_stdout_file
.ts_subsec
= 0;
634 zlog_file_set_other(&zt_stdout_file
);
636 zt_filterfile
.parent
.ts_subsec
= 0;
637 zlog_file_set_other(&zt_filterfile
.parent
);
641 DEFPY (config_log_ec
,
643 "[no] log error-category",
646 "Prefix log message text with [EC 9999] code\n")
648 zlog_set_prefix_ec(!no
);
652 DEFPY (config_log_xid
,
654 "[no] log unique-id",
657 "Prefix log message text with [XXXXX-XXXXX] identifier\n")
659 zlog_set_prefix_xid(!no
);
663 DEFPY (config_log_filterfile
,
664 config_log_filterfile_cmd
,
665 "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
667 "Logging to file with string filter\n"
671 int level
= log_default_lvl
;
674 level
= log_level_match(levelarg
);
675 if (level
== ZLOG_DISABLED
)
676 return CMD_ERR_NO_MATCH
;
678 return set_log_file(&zt_filterfile
.parent
, vty
, filename
, level
);
681 DEFUN (no_config_log_filterfile
,
682 no_config_log_filterfile_cmd
,
683 "no log filtered-file [FILENAME [LEVEL]]",
686 "Cancel logging to file with string filter\n"
687 "Logging file name\n"
690 zt_filterfile
.parent
.prio_min
= ZLOG_DISABLED
;
691 zlog_file_set_other(&zt_filterfile
.parent
);
697 "[no] log filter-text WORD$filter",
701 "String to filter by\n")
706 ret
= zlog_filter_del(filter
);
708 ret
= zlog_filter_add(filter
);
711 vty_out(vty
, "%% filter table full\n");
713 } else if (ret
!= 0) {
714 vty_out(vty
, "%% failed to %s log filter\n",
715 (no
? "remove" : "apply"));
719 vty_out(vty
, " %s\n", filter
);
723 /* Clear all log filters */
724 DEFPY (log_filter_clear
,
725 log_filter_clear_cmd
,
726 "clear log filter-text",
735 /* Show log filter */
736 DEFPY (show_log_filter
,
738 "show logging filter-text",
740 "Show current logging configuration\n"
743 char log_filters
[ZLOG_FILTERS_MAX
* (ZLOG_FILTER_LENGTH_MAX
+ 3)] = "";
746 len
= zlog_filter_dump(log_filters
, sizeof(log_filters
));
749 vty_out(vty
, "%% failed to get filters\n");
754 vty_out(vty
, "%s", log_filters
);
759 /* Enable/disable 'immediate' mode, with no output buffering */
760 DEFPY (log_immediate_mode
,
761 log_immediate_mode_cmd
,
762 "[no] log immediate-mode",
765 "Output immediately, without buffering\n")
767 zlog_set_immediate(!no
);
771 void log_config_write(struct vty
*vty
)
773 bool show_cmdline_hint
= false;
775 if (zt_file
.prio_min
!= ZLOG_DISABLED
&& zt_file
.filename
) {
776 vty_out(vty
, "log file %s", zt_file
.filename
);
778 if (zt_file
.prio_min
!= log_default_lvl
)
779 vty_out(vty
, " %s", zlog_priority
[zt_file
.prio_min
]);
783 if (zt_filterfile
.parent
.prio_min
!= ZLOG_DISABLED
784 && zt_filterfile
.parent
.filename
) {
785 vty_out(vty
, "log filtered-file %s",
786 zt_filterfile
.parent
.filename
);
788 if (zt_filterfile
.parent
.prio_min
!= log_default_lvl
)
790 zlog_priority
[zt_filterfile
.parent
.prio_min
]);
794 if (log_config_stdout_lvl
!= ZLOG_DISABLED
) {
795 vty_out(vty
, "log stdout");
797 if (log_config_stdout_lvl
!= log_default_lvl
)
799 zlog_priority
[log_config_stdout_lvl
]);
803 if (log_config_syslog_lvl
!= ZLOG_DISABLED
) {
804 vty_out(vty
, "log syslog");
806 if (log_config_syslog_lvl
!= log_default_lvl
)
808 zlog_priority
[log_config_syslog_lvl
]);
812 if (log_cmdline_syslog_lvl
!= ZLOG_DISABLED
) {
814 "! \"log syslog %s\" enabled by \"--log\" startup option\n",
815 zlog_priority
[log_cmdline_syslog_lvl
]);
816 show_cmdline_hint
= true;
818 if (log_cmdline_stdout_lvl
!= ZLOG_DISABLED
) {
820 "! \"log stdout %s\" enabled by \"--log\" startup option\n",
821 zlog_priority
[log_cmdline_stdout_lvl
]);
822 show_cmdline_hint
= true;
824 if (zt_file_cmdline
.prio_min
!= ZLOG_DISABLED
) {
826 "! \"log file %s %s\" enabled by \"--log\" startup option\n",
827 zt_file_cmdline
.filename
,
828 zlog_priority
[zt_file_cmdline
.prio_min
]);
829 show_cmdline_hint
= true;
831 if (show_cmdline_hint
)
833 "! use \"clear log cmdline-targets\" to remove this target\n");
835 if (zlog_syslog_get_facility() != LOG_DAEMON
)
836 vty_out(vty
, "log facility %s\n",
837 facility_name(zlog_syslog_get_facility()));
839 if (zt_file
.record_priority
== 1)
840 vty_out(vty
, "log record-priority\n");
842 if (zt_file
.ts_subsec
> 0)
843 vty_out(vty
, "log timestamp precision %d\n",
846 if (!zlog_get_prefix_ec())
847 vty_out(vty
, "no log error-category\n");
848 if (!zlog_get_prefix_xid())
849 vty_out(vty
, "no log unique-id\n");
851 if (logmsgs_with_persist_bt
) {
852 struct xrefdata
*xrd
;
853 struct xrefdata_logmsg
*xrdl
;
857 frr_each (xrefdata_uid
, &xrefdata_uid
, xrd
) {
858 if (xrd
->xref
->type
!= XREFT_LOGMSG
)
861 xrdl
= container_of(xrd
, struct xrefdata_logmsg
,
863 if (xrdl
->fl_print_bt
& LOGMSG_FLAG_PERSISTENT
)
864 vty_out(vty
, "debug unique-id %s backtrace\n",
870 static int log_vty_init(const char *progname
, const char *protoname
,
871 unsigned short instance
, uid_t uid
, gid_t gid
)
873 zlog_progname
= progname
;
874 zlog_protoname
= protoname
;
876 zlog_set_prefix_ec(true);
877 zlog_set_prefix_xid(true);
879 zlog_filterfile_init(&zt_filterfile
);
881 if (sd_stdout_is_journal
) {
882 stdout_journald_in_use
= true;
883 zlog_5424_init(&zt_stdout_journald
);
884 zlog_5424_apply_dst(&zt_stdout_journald
);
886 zlog_file_set_fd(&zt_stdout_file
, STDOUT_FILENO
);
890 __attribute__((_CONSTRUCTOR(475))) static void log_vty_preinit(void)
892 hook_register(zlog_init
, log_vty_init
);
895 void log_cmd_init(void)
897 install_element(VIEW_NODE
, &show_logging_cmd
);
898 install_element(ENABLE_NODE
, &clear_log_cmdline_cmd
);
900 install_element(CONFIG_NODE
, &config_log_stdout_cmd
);
901 install_element(CONFIG_NODE
, &no_config_log_stdout_cmd
);
902 install_element(CONFIG_NODE
, &config_log_monitor_cmd
);
903 install_element(CONFIG_NODE
, &no_config_log_monitor_cmd
);
904 install_element(CONFIG_NODE
, &config_log_file_cmd
);
905 install_element(CONFIG_NODE
, &no_config_log_file_cmd
);
906 install_element(CONFIG_NODE
, &config_log_syslog_cmd
);
907 install_element(CONFIG_NODE
, &no_config_log_syslog_cmd
);
908 install_element(CONFIG_NODE
, &config_log_facility_cmd
);
909 install_element(CONFIG_NODE
, &no_config_log_facility_cmd
);
910 install_element(CONFIG_NODE
, &config_log_record_priority_cmd
);
911 install_element(CONFIG_NODE
, &no_config_log_record_priority_cmd
);
912 install_element(CONFIG_NODE
, &config_log_timestamp_precision_cmd
);
913 install_element(CONFIG_NODE
, &no_config_log_timestamp_precision_cmd
);
914 install_element(CONFIG_NODE
, &config_log_ec_cmd
);
915 install_element(CONFIG_NODE
, &config_log_xid_cmd
);
917 install_element(VIEW_NODE
, &show_log_filter_cmd
);
918 install_element(CONFIG_NODE
, &log_filter_cmd
);
919 install_element(CONFIG_NODE
, &log_filter_clear_cmd
);
920 install_element(CONFIG_NODE
, &config_log_filterfile_cmd
);
921 install_element(CONFIG_NODE
, &no_config_log_filterfile_cmd
);
922 install_element(CONFIG_NODE
, &log_immediate_mode_cmd
);
924 install_element(ENABLE_NODE
, &debug_uid_backtrace_cmd
);
925 install_element(CONFIG_NODE
, &debug_uid_backtrace_cmd
);