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