1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2019 Cumulus Networks, Inc.
10 #include "lib/log_vty.h"
13 #include "lib/zlog_targets.h"
14 #include "lib/zlog_5424.h"
15 #include "lib/lib_errors.h"
16 #include "lib/printfrr.h"
17 #include "lib/systemd.h"
19 #include "lib/log_vty_clippy.c"
21 #define ZLOG_MAXLVL(a, b) MAX(a, b)
23 DEFINE_HOOK(zlog_rotate
, (), ());
24 DEFINE_HOOK(zlog_cli_show
, (struct vty
* vty
), (vty
));
26 static unsigned logmsgs_with_persist_bt
;
28 static const int log_default_lvl
= LOG_DEBUG
;
30 static int log_config_stdout_lvl
= ZLOG_DISABLED
;
31 static int log_config_syslog_lvl
= ZLOG_DISABLED
;
32 static int log_cmdline_stdout_lvl
= ZLOG_DISABLED
;
33 static int log_cmdline_syslog_lvl
= ZLOG_DISABLED
;
35 static struct zlog_cfg_file zt_file_cmdline
= {
36 .prio_min
= ZLOG_DISABLED
,
37 .ts_subsec
= LOG_TIMESTAMP_PRECISION
,
39 static struct zlog_cfg_file zt_file
= {
40 .prio_min
= ZLOG_DISABLED
,
41 .ts_subsec
= LOG_TIMESTAMP_PRECISION
,
43 static struct zlog_cfg_filterfile zt_filterfile
= {
46 .prio_min
= ZLOG_DISABLED
,
47 .ts_subsec
= LOG_TIMESTAMP_PRECISION
,
51 static struct zlog_cfg_file zt_stdout_file
= {
52 .prio_min
= ZLOG_DISABLED
,
53 .ts_subsec
= LOG_TIMESTAMP_PRECISION
,
55 static struct zlog_cfg_5424 zt_stdout_journald
= {
56 .prio_min
= ZLOG_DISABLED
,
58 .fmt
= ZLOG_FMT_JOURNALD
,
59 .dst
= ZLOG_5424_DST_UNIX
,
60 .filename
= "/run/systemd/journal/socket",
62 /* this can't be changed through config since this target substitutes
63 * in for the "plain" stdout target
65 .facility
= LOG_DAEMON
,
72 static bool stdout_journald_in_use
;
74 const char *zlog_progname
;
75 static const char *zlog_protoname
;
77 static const struct facility_map
{
81 } syslog_facilities
[] = {
82 {LOG_KERN
, "kern", 1},
83 {LOG_USER
, "user", 2},
84 {LOG_MAIL
, "mail", 1},
85 {LOG_DAEMON
, "daemon", 1},
86 {LOG_AUTH
, "auth", 1},
87 {LOG_SYSLOG
, "syslog", 1},
89 {LOG_NEWS
, "news", 1},
90 {LOG_UUCP
, "uucp", 2},
91 {LOG_CRON
, "cron", 1},
95 {LOG_LOCAL0
, "local0", 6},
96 {LOG_LOCAL1
, "local1", 6},
97 {LOG_LOCAL2
, "local2", 6},
98 {LOG_LOCAL3
, "local3", 6},
99 {LOG_LOCAL4
, "local4", 6},
100 {LOG_LOCAL5
, "local5", 6},
101 {LOG_LOCAL6
, "local6", 6},
102 {LOG_LOCAL7
, "local7", 6},
106 static const char * const zlog_priority
[] = {
107 "emergencies", "alerts", "critical", "errors", "warnings",
108 "notifications", "informational", "debugging", NULL
,
111 const char *zlog_priority_str(int priority
)
113 if (priority
> LOG_DEBUG
)
115 return zlog_priority
[priority
];
118 const char *facility_name(int facility
)
120 const struct facility_map
*fm
;
122 for (fm
= syslog_facilities
; fm
->name
; fm
++)
123 if (fm
->facility
== facility
)
128 int facility_match(const char *str
)
130 const struct facility_map
*fm
;
132 for (fm
= syslog_facilities
; fm
->name
; fm
++)
133 if (!strncmp(str
, fm
->name
, fm
->match
))
138 int log_level_match(const char *s
)
142 for (level
= 0; zlog_priority
[level
] != NULL
; level
++)
143 if (!strncmp(s
, zlog_priority
[level
], 2))
145 return ZLOG_DISABLED
;
148 void zlog_rotate(void)
150 zlog_file_rotate(&zt_file
);
151 zlog_file_rotate(&zt_filterfile
.parent
);
152 zlog_file_rotate(&zt_file_cmdline
);
153 hook_call(zlog_rotate
);
157 void log_show_syslog(struct vty
*vty
)
159 int level
= zlog_syslog_get_prio_min();
161 vty_out(vty
, "Syslog logging: ");
162 if (level
== ZLOG_DISABLED
)
163 vty_out(vty
, "disabled\n");
165 vty_out(vty
, "level %s, facility %s, ident %s\n",
166 zlog_priority
[level
],
167 facility_name(zlog_syslog_get_facility()),
171 DEFUN_NOSH (show_logging
,
175 "Show current logging configuration\n")
179 log_show_syslog(vty
);
181 stdout_prio
= stdout_journald_in_use
? zt_stdout_journald
.prio_min
182 : zt_stdout_file
.prio_min
;
184 vty_out(vty
, "Stdout logging: ");
185 if (stdout_prio
== ZLOG_DISABLED
)
186 vty_out(vty
, "disabled");
188 vty_out(vty
, "level %s", zlog_priority
[stdout_prio
]);
191 vty_out(vty
, "File logging: ");
192 if (zt_file
.prio_min
== ZLOG_DISABLED
|| !zt_file
.filename
)
193 vty_out(vty
, "disabled");
195 vty_out(vty
, "level %s, filename %s",
196 zlog_priority
[zt_file
.prio_min
], zt_file
.filename
);
199 if (zt_filterfile
.parent
.prio_min
!= ZLOG_DISABLED
200 && zt_filterfile
.parent
.filename
)
201 vty_out(vty
, "Filtered-file logging: level %s, filename %s\n",
202 zlog_priority
[zt_filterfile
.parent
.prio_min
],
203 zt_filterfile
.parent
.filename
);
205 if (log_cmdline_syslog_lvl
!= ZLOG_DISABLED
)
207 "From command line: \"--log syslog --log-level %s\"\n",
208 zlog_priority
[log_cmdline_syslog_lvl
]);
209 if (log_cmdline_stdout_lvl
!= ZLOG_DISABLED
)
211 "From command line: \"--log stdout --log-level %s\"\n",
212 zlog_priority
[log_cmdline_stdout_lvl
]);
213 if (zt_file_cmdline
.prio_min
!= ZLOG_DISABLED
)
215 "From command line: \"--log file:%s --log-level %s\"\n",
216 zt_file_cmdline
.filename
,
217 zlog_priority
[zt_file_cmdline
.prio_min
]);
219 vty_out(vty
, "Protocol name: %s\n", zlog_protoname
);
220 vty_out(vty
, "Record priority: %s\n",
221 (zt_file
.record_priority
? "enabled" : "disabled"));
222 vty_out(vty
, "Timestamp precision: %d\n", zt_file
.ts_subsec
);
224 hook_call(zlog_cli_show
, vty
);
228 static void log_stdout_apply_level(void)
232 maxlvl
= ZLOG_MAXLVL(log_config_stdout_lvl
, log_cmdline_stdout_lvl
);
234 if (stdout_journald_in_use
) {
235 zt_stdout_journald
.prio_min
= maxlvl
;
236 zlog_5424_apply_meta(&zt_stdout_journald
);
238 zt_stdout_file
.prio_min
= maxlvl
;
239 zlog_file_set_other(&zt_stdout_file
);
243 DEFPY (config_log_stdout
,
244 config_log_stdout_cmd
,
245 "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
247 "Set stdout logging level\n"
253 level
= log_level_match(levelarg
);
254 if (level
== ZLOG_DISABLED
)
255 return CMD_ERR_NO_MATCH
;
257 level
= log_default_lvl
;
259 log_config_stdout_lvl
= level
;
260 log_stdout_apply_level();
264 DEFUN (no_config_log_stdout
,
265 no_config_log_stdout_cmd
,
266 "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
269 "Cancel logging to stdout\n"
272 log_config_stdout_lvl
= ZLOG_DISABLED
;
273 log_stdout_apply_level();
277 DEFUN_HIDDEN (config_log_monitor
,
278 config_log_monitor_cmd
,
279 "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
281 "Set terminal line (monitor) logging level\n"
284 vty_out(vty
, "%% \"log monitor\" is deprecated and does nothing.\n");
288 DEFUN_HIDDEN (no_config_log_monitor
,
289 no_config_log_monitor_cmd
,
290 "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
293 "Disable terminal line (monitor) logging\n"
299 DEFPY_NOSH (debug_uid_backtrace
,
300 debug_uid_backtrace_cmd
,
301 "[no] debug unique-id UID backtrace",
304 "Options per individual log message, by unique ID\n"
305 "Log message unique ID (XXXXX-XXXXX)\n"
306 "Add backtrace to log when message is printed\n")
308 struct xrefdata search
, *xrd
;
309 struct xrefdata_logmsg
*xrdl
;
312 strlcpy(search
.uid
, uid
, sizeof(search
.uid
));
313 xrd
= xrefdata_uid_find(&xrefdata_uid
, &search
);
316 return CMD_ERR_NOTHING_TODO
;
318 if (xrd
->xref
->type
!= XREFT_LOGMSG
) {
319 vty_out(vty
, "%% ID \"%s\" is not a log message\n", uid
);
322 xrdl
= container_of(xrd
, struct xrefdata_logmsg
, xrefdata
);
324 flag
= (vty
->node
== CONFIG_NODE
) ? LOGMSG_FLAG_PERSISTENT
325 : LOGMSG_FLAG_EPHEMERAL
;
327 if ((xrdl
->fl_print_bt
& flag
) == (no
? 0 : flag
))
329 if (flag
== LOGMSG_FLAG_PERSISTENT
)
330 logmsgs_with_persist_bt
+= no
? -1 : 1;
332 xrdl
->fl_print_bt
^= flag
;
336 static int set_log_file(struct zlog_cfg_file
*target
, struct vty
*vty
,
337 const char *fname
, int loglevel
)
339 char path
[MAXPATHLEN
+ 1];
340 const char *fullpath
;
344 /* Path detection. */
345 if (!IS_DIRECTORY_SEP(*fname
)) {
346 char cwd
[MAXPATHLEN
+ 1];
348 cwd
[MAXPATHLEN
] = '\0';
350 if (getcwd(cwd
, MAXPATHLEN
) == NULL
) {
351 flog_err_sys(EC_LIB_SYSTEM_CALL
,
352 "config_log_file: Unable to alloc mem!");
353 return CMD_WARNING_CONFIG_FAILED
;
356 int pr
= snprintf(path
, sizeof(path
), "%s/%s", cwd
, fname
);
357 if (pr
< 0 || (unsigned int)pr
>= sizeof(path
)) {
360 "%s: Path too long ('%s/%s'); system maximum is %u",
361 __func__
, cwd
, fname
, MAXPATHLEN
);
362 return CMD_WARNING_CONFIG_FAILED
;
369 target
->prio_min
= loglevel
;
370 ok
= zlog_file_set_filename(target
, fullpath
);
374 vty_out(vty
, "can't open logfile %s\n", fname
);
375 return CMD_WARNING_CONFIG_FAILED
;
380 void command_setup_early_logging(const char *dest
, const char *level
)
388 nlevel
= log_level_match(level
);
390 if (nlevel
== ZLOG_DISABLED
) {
391 fprintf(stderr
, "invalid log level \"%s\"\n", level
);
395 nlevel
= log_default_lvl
;
400 sep
= strchr(dest
, ':');
401 len
= sep
? (int)(sep
- dest
) : (int)strlen(dest
);
403 snprintfrr(type
, sizeof(type
), "%.*s", len
, dest
);
405 if (strcmp(type
, "stdout") == 0) {
406 log_cmdline_stdout_lvl
= nlevel
;
407 log_stdout_apply_level();
410 if (strcmp(type
, "syslog") == 0) {
411 log_cmdline_syslog_lvl
= nlevel
;
412 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
413 log_cmdline_syslog_lvl
));
416 if (strcmp(type
, "file") == 0 && sep
) {
418 set_log_file(&zt_file_cmdline
, NULL
, sep
, nlevel
);
421 if (strcmp(type
, "monitor") == 0 && sep
) {
422 struct zlog_live_cfg cfg
= {};
427 fd
= strtoul(sep
, &endp
, 10);
428 if (!*sep
|| *endp
) {
429 fprintf(stderr
, "invalid monitor fd \"%s\"\n", sep
);
433 zlog_live_open_fd(&cfg
, nlevel
, fd
);
434 zlog_live_disown(&cfg
);
438 fprintf(stderr
, "invalid log target \"%s\" (\"%s\")\n", type
, dest
);
442 DEFUN (clear_log_cmdline
,
443 clear_log_cmdline_cmd
,
444 "clear log cmdline-targets",
447 "Disable log targets specified at startup by --log option\n")
449 zt_file_cmdline
.prio_min
= ZLOG_DISABLED
;
450 zlog_file_set_other(&zt_file_cmdline
);
452 log_cmdline_syslog_lvl
= ZLOG_DISABLED
;
453 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
454 log_cmdline_syslog_lvl
));
456 log_cmdline_stdout_lvl
= ZLOG_DISABLED
;
457 log_stdout_apply_level();
462 DEFPY (config_log_file
,
464 "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
470 int level
= log_default_lvl
;
473 level
= log_level_match(levelarg
);
474 if (level
== ZLOG_DISABLED
)
475 return CMD_ERR_NO_MATCH
;
477 return set_log_file(&zt_file
, vty
, filename
, level
);
480 DEFUN (no_config_log_file
,
481 no_config_log_file_cmd
,
482 "no log file [FILENAME [LEVEL]]",
485 "Cancel logging to file\n"
486 "Logging file name\n"
489 zt_file
.prio_min
= ZLOG_DISABLED
;
490 zlog_file_set_other(&zt_file
);
494 DEFPY (config_log_syslog
,
495 config_log_syslog_cmd
,
496 "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
498 "Set syslog logging level\n"
504 level
= log_level_match(levelarg
);
506 if (level
== ZLOG_DISABLED
)
507 return CMD_ERR_NO_MATCH
;
509 level
= log_default_lvl
;
511 log_config_syslog_lvl
= level
;
512 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
513 log_cmdline_syslog_lvl
));
517 DEFUN (no_config_log_syslog
,
518 no_config_log_syslog_cmd
,
519 "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>]",
522 "Cancel logging to syslog\n"
526 log_config_syslog_lvl
= ZLOG_DISABLED
;
527 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl
,
528 log_cmdline_syslog_lvl
));
532 DEFPY (config_log_facility
,
533 config_log_facility_cmd
,
534 "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>$facilityarg",
536 "Facility parameter for syslog messages\n"
539 int facility
= facility_match(facilityarg
);
541 zlog_syslog_set_facility(facility
);
545 DEFUN (no_config_log_facility
,
546 no_config_log_facility_cmd
,
547 "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
550 "Reset syslog facility to default (daemon)\n"
553 zlog_syslog_set_facility(LOG_DAEMON
);
557 DEFUN (config_log_record_priority
,
558 config_log_record_priority_cmd
,
559 "log record-priority",
561 "Log the priority of the message within the message\n")
563 zt_file
.record_priority
= true;
564 zlog_file_set_other(&zt_file
);
565 if (!stdout_journald_in_use
) {
566 zt_stdout_file
.record_priority
= true;
567 zlog_file_set_other(&zt_stdout_file
);
569 zt_filterfile
.parent
.record_priority
= true;
570 zlog_file_set_other(&zt_filterfile
.parent
);
574 DEFUN (no_config_log_record_priority
,
575 no_config_log_record_priority_cmd
,
576 "no log record-priority",
579 "Do not log the priority of the message within the message\n")
581 zt_file
.record_priority
= false;
582 zlog_file_set_other(&zt_file
);
583 if (!stdout_journald_in_use
) {
584 zt_stdout_file
.record_priority
= false;
585 zlog_file_set_other(&zt_stdout_file
);
587 zt_filterfile
.parent
.record_priority
= false;
588 zlog_file_set_other(&zt_filterfile
.parent
);
592 DEFPY (config_log_timestamp_precision
,
593 config_log_timestamp_precision_cmd
,
594 "log timestamp precision (0-6)",
596 "Timestamp configuration\n"
597 "Set the timestamp precision\n"
598 "Number of subsecond digits\n")
600 zt_file
.ts_subsec
= precision
;
601 zlog_file_set_other(&zt_file
);
602 if (!stdout_journald_in_use
) {
603 zt_stdout_file
.ts_subsec
= precision
;
604 zlog_file_set_other(&zt_stdout_file
);
606 zt_filterfile
.parent
.ts_subsec
= precision
;
607 zlog_file_set_other(&zt_filterfile
.parent
);
611 DEFUN (no_config_log_timestamp_precision
,
612 no_config_log_timestamp_precision_cmd
,
613 "no log timestamp precision [(0-6)]",
616 "Timestamp configuration\n"
617 "Reset the timestamp precision to the default value of 0\n"
618 "Number of subsecond digits\n")
620 zt_file
.ts_subsec
= 0;
621 zlog_file_set_other(&zt_file
);
622 if (!stdout_journald_in_use
) {
623 zt_stdout_file
.ts_subsec
= 0;
624 zlog_file_set_other(&zt_stdout_file
);
626 zt_filterfile
.parent
.ts_subsec
= 0;
627 zlog_file_set_other(&zt_filterfile
.parent
);
631 DEFPY (config_log_ec
,
633 "[no] log error-category",
636 "Prefix log message text with [EC 9999] code\n")
638 zlog_set_prefix_ec(!no
);
642 DEFPY (config_log_xid
,
644 "[no] log unique-id",
647 "Prefix log message text with [XXXXX-XXXXX] identifier\n")
649 zlog_set_prefix_xid(!no
);
653 DEFPY (config_log_filterfile
,
654 config_log_filterfile_cmd
,
655 "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
657 "Logging to file with string filter\n"
661 int level
= log_default_lvl
;
664 level
= log_level_match(levelarg
);
665 if (level
== ZLOG_DISABLED
)
666 return CMD_ERR_NO_MATCH
;
668 return set_log_file(&zt_filterfile
.parent
, vty
, filename
, level
);
671 DEFUN (no_config_log_filterfile
,
672 no_config_log_filterfile_cmd
,
673 "no log filtered-file [FILENAME [LEVEL]]",
676 "Cancel logging to file with string filter\n"
677 "Logging file name\n"
680 zt_filterfile
.parent
.prio_min
= ZLOG_DISABLED
;
681 zlog_file_set_other(&zt_filterfile
.parent
);
687 "[no] log filter-text WORD$filter",
691 "String to filter by\n")
696 ret
= zlog_filter_del(filter
);
698 ret
= zlog_filter_add(filter
);
701 vty_out(vty
, "%% filter table full\n");
703 } else if (ret
!= 0) {
704 vty_out(vty
, "%% failed to %s log filter\n",
705 (no
? "remove" : "apply"));
709 vty_out(vty
, " %s\n", filter
);
713 /* Clear all log filters */
714 DEFPY (log_filter_clear
,
715 log_filter_clear_cmd
,
716 "clear log filter-text",
725 /* Show log filter */
726 DEFPY (show_log_filter
,
728 "show logging filter-text",
730 "Show current logging configuration\n"
733 char log_filters
[ZLOG_FILTERS_MAX
* (ZLOG_FILTER_LENGTH_MAX
+ 3)] = "";
736 len
= zlog_filter_dump(log_filters
, sizeof(log_filters
));
739 vty_out(vty
, "%% failed to get filters\n");
744 vty_out(vty
, "%s", log_filters
);
749 /* Enable/disable 'immediate' mode, with no output buffering */
750 DEFPY (log_immediate_mode
,
751 log_immediate_mode_cmd
,
752 "[no] log immediate-mode",
755 "Output immediately, without buffering\n")
757 zlog_set_immediate(!no
);
761 void log_config_write(struct vty
*vty
)
763 bool show_cmdline_hint
= false;
765 if (zt_file
.prio_min
!= ZLOG_DISABLED
&& zt_file
.filename
) {
766 vty_out(vty
, "log file %s", zt_file
.filename
);
768 if (zt_file
.prio_min
!= log_default_lvl
)
769 vty_out(vty
, " %s", zlog_priority
[zt_file
.prio_min
]);
773 if (zt_filterfile
.parent
.prio_min
!= ZLOG_DISABLED
774 && zt_filterfile
.parent
.filename
) {
775 vty_out(vty
, "log filtered-file %s",
776 zt_filterfile
.parent
.filename
);
778 if (zt_filterfile
.parent
.prio_min
!= log_default_lvl
)
780 zlog_priority
[zt_filterfile
.parent
.prio_min
]);
784 if (log_config_stdout_lvl
!= ZLOG_DISABLED
) {
785 vty_out(vty
, "log stdout");
787 if (log_config_stdout_lvl
!= log_default_lvl
)
789 zlog_priority
[log_config_stdout_lvl
]);
793 if (log_config_syslog_lvl
!= ZLOG_DISABLED
) {
794 vty_out(vty
, "log syslog");
796 if (log_config_syslog_lvl
!= log_default_lvl
)
798 zlog_priority
[log_config_syslog_lvl
]);
802 if (log_cmdline_syslog_lvl
!= ZLOG_DISABLED
) {
804 "! \"log syslog %s\" enabled by \"--log\" startup option\n",
805 zlog_priority
[log_cmdline_syslog_lvl
]);
806 show_cmdline_hint
= true;
808 if (log_cmdline_stdout_lvl
!= ZLOG_DISABLED
) {
810 "! \"log stdout %s\" enabled by \"--log\" startup option\n",
811 zlog_priority
[log_cmdline_stdout_lvl
]);
812 show_cmdline_hint
= true;
814 if (zt_file_cmdline
.prio_min
!= ZLOG_DISABLED
) {
816 "! \"log file %s %s\" enabled by \"--log\" startup option\n",
817 zt_file_cmdline
.filename
,
818 zlog_priority
[zt_file_cmdline
.prio_min
]);
819 show_cmdline_hint
= true;
821 if (show_cmdline_hint
)
823 "! use \"clear log cmdline-targets\" to remove this target\n");
825 if (zlog_syslog_get_facility() != LOG_DAEMON
)
826 vty_out(vty
, "log facility %s\n",
827 facility_name(zlog_syslog_get_facility()));
829 if (zt_file
.record_priority
== 1)
830 vty_out(vty
, "log record-priority\n");
832 if (zt_file
.ts_subsec
> 0)
833 vty_out(vty
, "log timestamp precision %d\n",
836 if (!zlog_get_prefix_ec())
837 vty_out(vty
, "no log error-category\n");
838 if (!zlog_get_prefix_xid())
839 vty_out(vty
, "no log unique-id\n");
841 if (logmsgs_with_persist_bt
) {
842 struct xrefdata
*xrd
;
843 struct xrefdata_logmsg
*xrdl
;
847 frr_each (xrefdata_uid
, &xrefdata_uid
, xrd
) {
848 if (xrd
->xref
->type
!= XREFT_LOGMSG
)
851 xrdl
= container_of(xrd
, struct xrefdata_logmsg
,
853 if (xrdl
->fl_print_bt
& LOGMSG_FLAG_PERSISTENT
)
854 vty_out(vty
, "debug unique-id %s backtrace\n",
860 static int log_vty_init(const char *progname
, const char *protoname
,
861 unsigned short instance
, uid_t uid
, gid_t gid
)
863 zlog_progname
= progname
;
864 zlog_protoname
= protoname
;
866 zlog_set_prefix_ec(true);
867 zlog_set_prefix_xid(true);
869 zlog_filterfile_init(&zt_filterfile
);
871 if (sd_stdout_is_journal
) {
872 stdout_journald_in_use
= true;
873 zlog_5424_init(&zt_stdout_journald
);
874 zlog_5424_apply_dst(&zt_stdout_journald
);
876 zlog_file_set_fd(&zt_stdout_file
, STDOUT_FILENO
);
880 __attribute__((_CONSTRUCTOR(475))) static void log_vty_preinit(void)
882 hook_register(zlog_init
, log_vty_init
);
885 void log_cmd_init(void)
887 install_element(VIEW_NODE
, &show_logging_cmd
);
888 install_element(ENABLE_NODE
, &clear_log_cmdline_cmd
);
890 install_element(CONFIG_NODE
, &config_log_stdout_cmd
);
891 install_element(CONFIG_NODE
, &no_config_log_stdout_cmd
);
892 install_element(CONFIG_NODE
, &config_log_monitor_cmd
);
893 install_element(CONFIG_NODE
, &no_config_log_monitor_cmd
);
894 install_element(CONFIG_NODE
, &config_log_file_cmd
);
895 install_element(CONFIG_NODE
, &no_config_log_file_cmd
);
896 install_element(CONFIG_NODE
, &config_log_syslog_cmd
);
897 install_element(CONFIG_NODE
, &no_config_log_syslog_cmd
);
898 install_element(CONFIG_NODE
, &config_log_facility_cmd
);
899 install_element(CONFIG_NODE
, &no_config_log_facility_cmd
);
900 install_element(CONFIG_NODE
, &config_log_record_priority_cmd
);
901 install_element(CONFIG_NODE
, &no_config_log_record_priority_cmd
);
902 install_element(CONFIG_NODE
, &config_log_timestamp_precision_cmd
);
903 install_element(CONFIG_NODE
, &no_config_log_timestamp_precision_cmd
);
904 install_element(CONFIG_NODE
, &config_log_ec_cmd
);
905 install_element(CONFIG_NODE
, &config_log_xid_cmd
);
907 install_element(VIEW_NODE
, &show_log_filter_cmd
);
908 install_element(CONFIG_NODE
, &log_filter_cmd
);
909 install_element(CONFIG_NODE
, &log_filter_clear_cmd
);
910 install_element(CONFIG_NODE
, &config_log_filterfile_cmd
);
911 install_element(CONFIG_NODE
, &no_config_log_filterfile_cmd
);
912 install_element(CONFIG_NODE
, &log_immediate_mode_cmd
);
914 install_element(ENABLE_NODE
, &debug_uid_backtrace_cmd
);
915 install_element(CONFIG_NODE
, &debug_uid_backtrace_cmd
);