back to topotato report
topotato coverage report
Current view: top level - lib - log_vty.c (source / functions) Hit Total Coverage
Test: test_pim6_bootstrap.py::PIM6Bootstrap Lines: 119 396 30.1 %
Date: 2023-02-16 02:07:22 Functions: 11 34 32.4 %

          Line data    Source code
       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/zlog_5424.h"
      28             : #include "lib/lib_errors.h"
      29             : #include "lib/printfrr.h"
      30             : #include "lib/systemd.h"
      31             : 
      32             : #include "lib/log_vty_clippy.c"
      33             : 
      34             : #define ZLOG_MAXLVL(a, b) MAX(a, b)
      35             : 
      36           0 : DEFINE_HOOK(zlog_rotate, (), ());
      37           0 : DEFINE_HOOK(zlog_cli_show, (struct vty * vty), (vty));
      38             : 
      39             : static unsigned logmsgs_with_persist_bt;
      40             : 
      41             : static const int log_default_lvl = LOG_DEBUG;
      42             : 
      43             : static int log_config_stdout_lvl = ZLOG_DISABLED;
      44             : static int log_config_syslog_lvl = ZLOG_DISABLED;
      45             : static int log_cmdline_stdout_lvl = ZLOG_DISABLED;
      46             : static int log_cmdline_syslog_lvl = ZLOG_DISABLED;
      47             : 
      48             : static struct zlog_cfg_file zt_file_cmdline = {
      49             :         .prio_min = ZLOG_DISABLED,
      50             : };
      51             : static struct zlog_cfg_file zt_file = {
      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 struct zlog_cfg_file zt_stdout_file = {
      61             :         .prio_min = ZLOG_DISABLED,
      62             : };
      63             : static struct zlog_cfg_5424 zt_stdout_journald = {
      64             :         .prio_min = ZLOG_DISABLED,
      65             : 
      66             :         .fmt = ZLOG_FMT_JOURNALD,
      67             :         .dst = ZLOG_5424_DST_UNIX,
      68             :         .filename = "/run/systemd/journal/socket",
      69             : 
      70             :         /* this can't be changed through config since this target substitutes
      71             :          * in for the "plain" stdout target
      72             :          */
      73             :         .facility = LOG_DAEMON,
      74             :         .kw_version = false,
      75             :         .kw_location = true,
      76             :         .kw_uid = true,
      77             :         .kw_ec = true,
      78             :         .kw_args = true,
      79             : };
      80             : static bool stdout_journald_in_use;
      81             : 
      82             : const char *zlog_progname;
      83             : static const char *zlog_protoname;
      84             : 
      85             : static const struct facility_map {
      86             :         int facility;
      87             :         const char *name;
      88             :         size_t match;
      89             : } syslog_facilities[] = {
      90             :         {LOG_KERN, "kern", 1},
      91             :         {LOG_USER, "user", 2},
      92             :         {LOG_MAIL, "mail", 1},
      93             :         {LOG_DAEMON, "daemon", 1},
      94             :         {LOG_AUTH, "auth", 1},
      95             :         {LOG_SYSLOG, "syslog", 1},
      96             :         {LOG_LPR, "lpr", 2},
      97             :         {LOG_NEWS, "news", 1},
      98             :         {LOG_UUCP, "uucp", 2},
      99             :         {LOG_CRON, "cron", 1},
     100             : #ifdef LOG_FTP
     101             :         {LOG_FTP, "ftp", 1},
     102             : #endif
     103             :         {LOG_LOCAL0, "local0", 6},
     104             :         {LOG_LOCAL1, "local1", 6},
     105             :         {LOG_LOCAL2, "local2", 6},
     106             :         {LOG_LOCAL3, "local3", 6},
     107             :         {LOG_LOCAL4, "local4", 6},
     108             :         {LOG_LOCAL5, "local5", 6},
     109             :         {LOG_LOCAL6, "local6", 6},
     110             :         {LOG_LOCAL7, "local7", 6},
     111             :         {0, NULL, 0},
     112             : };
     113             : 
     114             : static const char * const zlog_priority[] = {
     115             :         "emergencies",   "alerts",  "critical",  "errors", "warnings",
     116             :         "notifications", "informational", "debugging", NULL,
     117             : };
     118             : 
     119           0 : const char *zlog_priority_str(int priority)
     120             : {
     121           0 :         if (priority > LOG_DEBUG)
     122             :                 return "???";
     123           0 :         return zlog_priority[priority];
     124             : }
     125             : 
     126           0 : const char *facility_name(int facility)
     127             : {
     128           0 :         const struct facility_map *fm;
     129             : 
     130           0 :         for (fm = syslog_facilities; fm->name; fm++)
     131           0 :                 if (fm->facility == facility)
     132           0 :                         return fm->name;
     133             :         return "";
     134             : }
     135             : 
     136           0 : int facility_match(const char *str)
     137             : {
     138           0 :         const struct facility_map *fm;
     139             : 
     140           0 :         for (fm = syslog_facilities; fm->name; fm++)
     141           0 :                 if (!strncmp(str, fm->name, fm->match))
     142           0 :                         return fm->facility;
     143             :         return -1;
     144             : }
     145             : 
     146           6 : int log_level_match(const char *s)
     147             : {
     148           6 :         int level;
     149             : 
     150          48 :         for (level = 0; zlog_priority[level] != NULL; level++)
     151          48 :                 if (!strncmp(s, zlog_priority[level], 2))
     152           6 :                         return level;
     153             :         return ZLOG_DISABLED;
     154             : }
     155             : 
     156           0 : void zlog_rotate(void)
     157             : {
     158           0 :         zlog_file_rotate(&zt_file);
     159           0 :         zlog_file_rotate(&zt_filterfile.parent);
     160           0 :         zlog_file_rotate(&zt_file_cmdline);
     161           0 :         hook_call(zlog_rotate);
     162           0 : }
     163             : 
     164             : 
     165           0 : void log_show_syslog(struct vty *vty)
     166             : {
     167           0 :         int level = zlog_syslog_get_prio_min();
     168             : 
     169           0 :         vty_out(vty, "Syslog logging: ");
     170           0 :         if (level == ZLOG_DISABLED)
     171           0 :                 vty_out(vty, "disabled\n");
     172             :         else
     173           0 :                 vty_out(vty, "level %s, facility %s, ident %s\n",
     174           0 :                         zlog_priority[level],
     175             :                         facility_name(zlog_syslog_get_facility()),
     176             :                         zlog_progname);
     177           0 : }
     178             : 
     179           0 : DEFUN_NOSH (show_logging,
     180             :             show_logging_cmd,
     181             :             "show logging",
     182             :             SHOW_STR
     183             :             "Show current logging configuration\n")
     184             : {
     185           0 :         int stdout_prio;
     186             : 
     187           0 :         log_show_syslog(vty);
     188             : 
     189           0 :         stdout_prio = stdout_journald_in_use ? zt_stdout_journald.prio_min
     190           0 :                                              : zt_stdout_file.prio_min;
     191             : 
     192           0 :         vty_out(vty, "Stdout logging: ");
     193           0 :         if (stdout_prio == ZLOG_DISABLED)
     194           0 :                 vty_out(vty, "disabled");
     195             :         else
     196           0 :                 vty_out(vty, "level %s", zlog_priority[stdout_prio]);
     197           0 :         vty_out(vty, "\n");
     198             : 
     199           0 :         vty_out(vty, "File logging: ");
     200           0 :         if (zt_file.prio_min == ZLOG_DISABLED || !zt_file.filename)
     201           0 :                 vty_out(vty, "disabled");
     202             :         else
     203           0 :                 vty_out(vty, "level %s, filename %s",
     204           0 :                         zlog_priority[zt_file.prio_min], zt_file.filename);
     205           0 :         vty_out(vty, "\n");
     206             : 
     207           0 :         if (zt_filterfile.parent.prio_min != ZLOG_DISABLED
     208           0 :             && zt_filterfile.parent.filename)
     209           0 :                 vty_out(vty, "Filtered-file logging: level %s, filename %s\n",
     210           0 :                         zlog_priority[zt_filterfile.parent.prio_min],
     211             :                         zt_filterfile.parent.filename);
     212             : 
     213           0 :         if (log_cmdline_syslog_lvl != ZLOG_DISABLED)
     214           0 :                 vty_out(vty,
     215             :                         "From command line: \"--log syslog --log-level %s\"\n",
     216           0 :                         zlog_priority[log_cmdline_syslog_lvl]);
     217           0 :         if (log_cmdline_stdout_lvl != ZLOG_DISABLED)
     218           0 :                 vty_out(vty,
     219             :                         "From command line: \"--log stdout --log-level %s\"\n",
     220           0 :                         zlog_priority[log_cmdline_stdout_lvl]);
     221           0 :         if (zt_file_cmdline.prio_min != ZLOG_DISABLED)
     222           0 :                 vty_out(vty,
     223             :                         "From command line: \"--log file:%s --log-level %s\"\n",
     224             :                         zt_file_cmdline.filename,
     225           0 :                         zlog_priority[zt_file_cmdline.prio_min]);
     226             : 
     227           0 :         vty_out(vty, "Protocol name: %s\n", zlog_protoname);
     228           0 :         vty_out(vty, "Record priority: %s\n",
     229           0 :                 (zt_file.record_priority ? "enabled" : "disabled"));
     230           0 :         vty_out(vty, "Timestamp precision: %d\n", zt_file.ts_subsec);
     231             : 
     232           0 :         hook_call(zlog_cli_show, vty);
     233           0 :         return CMD_SUCCESS;
     234             : }
     235             : 
     236           3 : static void log_stdout_apply_level(void)
     237             : {
     238           3 :         int maxlvl;
     239             : 
     240           3 :         maxlvl = ZLOG_MAXLVL(log_config_stdout_lvl, log_cmdline_stdout_lvl);
     241             : 
     242           3 :         if (stdout_journald_in_use) {
     243           0 :                 zt_stdout_journald.prio_min = maxlvl;
     244           0 :                 zlog_5424_apply_meta(&zt_stdout_journald);
     245             :         } else {
     246           3 :                 zt_stdout_file.prio_min = maxlvl;
     247           3 :                 zlog_file_set_other(&zt_stdout_file);
     248             :         }
     249           3 : }
     250             : 
     251           0 : DEFPY (config_log_stdout,
     252             :        config_log_stdout_cmd,
     253             :        "log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
     254             :        "Logging control\n"
     255             :        "Set stdout logging level\n"
     256             :        LOG_LEVEL_DESC)
     257             : {
     258           0 :         int level;
     259             : 
     260           0 :         if (levelarg) {
     261           0 :                 level = log_level_match(levelarg);
     262           0 :                 if (level == ZLOG_DISABLED)
     263             :                         return CMD_ERR_NO_MATCH;
     264             :         } else
     265             :                 level = log_default_lvl;
     266             : 
     267           0 :         log_config_stdout_lvl = level;
     268           0 :         log_stdout_apply_level();
     269           0 :         return CMD_SUCCESS;
     270             : }
     271             : 
     272           0 : DEFUN (no_config_log_stdout,
     273             :        no_config_log_stdout_cmd,
     274             :        "no log stdout [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
     275             :        NO_STR
     276             :        "Logging control\n"
     277             :        "Cancel logging to stdout\n"
     278             :        LOG_LEVEL_DESC)
     279             : {
     280           0 :         log_config_stdout_lvl = ZLOG_DISABLED;
     281           0 :         log_stdout_apply_level();
     282           0 :         return CMD_SUCCESS;
     283             : }
     284             : 
     285           0 : DEFUN_HIDDEN (config_log_monitor,
     286             :        config_log_monitor_cmd,
     287             :        "log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
     288             :        "Logging control\n"
     289             :        "Set terminal line (monitor) logging level\n"
     290             :        LOG_LEVEL_DESC)
     291             : {
     292           0 :         vty_out(vty, "%% \"log monitor\" is deprecated and does nothing.\n");
     293           0 :         return CMD_SUCCESS;
     294             : }
     295             : 
     296           0 : DEFUN_HIDDEN (no_config_log_monitor,
     297             :        no_config_log_monitor_cmd,
     298             :        "no log monitor [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>]",
     299             :        NO_STR
     300             :        "Logging control\n"
     301             :        "Disable terminal line (monitor) logging\n"
     302             :        LOG_LEVEL_DESC)
     303             : {
     304           0 :         return CMD_SUCCESS;
     305             : }
     306             : 
     307           0 : DEFPY_NOSH (debug_uid_backtrace,
     308             :             debug_uid_backtrace_cmd,
     309             :             "[no] debug unique-id UID backtrace",
     310             :             NO_STR
     311             :             DEBUG_STR
     312             :             "Options per individual log message, by unique ID\n"
     313             :             "Log message unique ID (XXXXX-XXXXX)\n"
     314             :             "Add backtrace to log when message is printed\n")
     315             : {
     316           0 :         struct xrefdata search, *xrd;
     317           0 :         struct xrefdata_logmsg *xrdl;
     318           0 :         uint8_t flag;
     319             : 
     320           0 :         strlcpy(search.uid, uid, sizeof(search.uid));
     321           0 :         xrd = xrefdata_uid_find(&xrefdata_uid, &search);
     322             : 
     323           0 :         if (!xrd)
     324             :                 return CMD_ERR_NOTHING_TODO;
     325             : 
     326           0 :         if (xrd->xref->type != XREFT_LOGMSG) {
     327           0 :                 vty_out(vty, "%% ID \"%s\" is not a log message\n", uid);
     328           0 :                 return CMD_WARNING;
     329             :         }
     330           0 :         xrdl = container_of(xrd, struct xrefdata_logmsg, xrefdata);
     331             : 
     332           0 :         flag = (vty->node == CONFIG_NODE) ? LOGMSG_FLAG_PERSISTENT
     333             :                                           : LOGMSG_FLAG_EPHEMERAL;
     334             : 
     335           0 :         if ((xrdl->fl_print_bt & flag) == (no ? 0 : flag))
     336             :                 return CMD_SUCCESS;
     337           0 :         if (flag == LOGMSG_FLAG_PERSISTENT)
     338           0 :                 logmsgs_with_persist_bt += no ? -1 : 1;
     339             : 
     340           0 :         xrdl->fl_print_bt ^= flag;
     341           0 :         return CMD_SUCCESS;
     342             : }
     343             : 
     344           6 : static int set_log_file(struct zlog_cfg_file *target, struct vty *vty,
     345             :                         const char *fname, int loglevel)
     346             : {
     347           6 :         char path[MAXPATHLEN + 1];
     348           6 :         const char *fullpath;
     349           6 :         bool ok;
     350             : 
     351             : 
     352             :         /* Path detection. */
     353           6 :         if (!IS_DIRECTORY_SEP(*fname)) {
     354           0 :                 char cwd[MAXPATHLEN + 1];
     355             : 
     356           0 :                 cwd[MAXPATHLEN] = '\0';
     357             : 
     358           0 :                 if (getcwd(cwd, MAXPATHLEN) == NULL) {
     359           0 :                         flog_err_sys(EC_LIB_SYSTEM_CALL,
     360             :                                      "config_log_file: Unable to alloc mem!");
     361           0 :                         return CMD_WARNING_CONFIG_FAILED;
     362             :                 }
     363             : 
     364           0 :                 int pr = snprintf(path, sizeof(path), "%s/%s", cwd, fname);
     365           0 :                 if (pr < 0 || (unsigned int)pr >= sizeof(path)) {
     366           0 :                         flog_err_sys(
     367             :                                 EC_LIB_SYSTEM_CALL,
     368             :                                 "%s: Path too long ('%s/%s'); system maximum is %u",
     369             :                                 __func__, cwd, fname, MAXPATHLEN);
     370           0 :                         return CMD_WARNING_CONFIG_FAILED;
     371             :                 }
     372             : 
     373           0 :                 fullpath = path;
     374             :         } else
     375             :                 fullpath = fname;
     376             : 
     377           6 :         target->prio_min = loglevel;
     378           6 :         ok = zlog_file_set_filename(target, fullpath);
     379             : 
     380           6 :         if (!ok) {
     381           0 :                 if (vty)
     382           0 :                         vty_out(vty, "can't open logfile %s\n", fname);
     383           0 :                 return CMD_WARNING_CONFIG_FAILED;
     384             :         }
     385             :         return CMD_SUCCESS;
     386             : }
     387             : 
     388           6 : void command_setup_early_logging(const char *dest, const char *level)
     389             : {
     390           6 :         int nlevel;
     391           6 :         char *sep;
     392           6 :         int len;
     393           6 :         char type[8];
     394             : 
     395           6 :         if (level) {
     396           6 :                 nlevel = log_level_match(level);
     397             : 
     398           6 :                 if (nlevel == ZLOG_DISABLED) {
     399           0 :                         fprintf(stderr, "invalid log level \"%s\"\n", level);
     400           0 :                         exit(1);
     401             :                 }
     402             :         } else
     403             :                 nlevel = log_default_lvl;
     404             : 
     405           6 :         if (!dest)
     406             :                 return;
     407             : 
     408           6 :         sep = strchr(dest, ':');
     409           6 :         len = sep ? (int)(sep - dest) : (int)strlen(dest);
     410             : 
     411           6 :         snprintfrr(type, sizeof(type), "%.*s", len, dest);
     412             : 
     413           6 :         if (strcmp(type, "stdout") == 0) {
     414           0 :                 log_cmdline_stdout_lvl = nlevel;
     415           0 :                 log_stdout_apply_level();
     416           0 :                 return;
     417             :         }
     418           6 :         if (strcmp(type, "syslog") == 0) {
     419           0 :                 log_cmdline_syslog_lvl = nlevel;
     420           0 :                 zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
     421             :                                                      log_cmdline_syslog_lvl));
     422           0 :                 return;
     423             :         }
     424           6 :         if (strcmp(type, "file") == 0 && sep) {
     425           3 :                 sep++;
     426           3 :                 set_log_file(&zt_file_cmdline, NULL, sep, nlevel);
     427           3 :                 return;
     428             :         }
     429           3 :         if (strcmp(type, "monitor") == 0 && sep) {
     430           3 :                 struct zlog_live_cfg cfg = {};
     431           3 :                 unsigned long fd;
     432           3 :                 char *endp;
     433             : 
     434           3 :                 sep++;
     435           3 :                 fd = strtoul(sep, &endp, 10);
     436           3 :                 if (!*sep || *endp) {
     437           0 :                         fprintf(stderr, "invalid monitor fd \"%s\"\n", sep);
     438           0 :                         exit(1);
     439             :                 }
     440             : 
     441           3 :                 zlog_live_open_fd(&cfg, nlevel, fd);
     442           3 :                 zlog_live_disown(&cfg);
     443           3 :                 return;
     444             :         }
     445             : 
     446           0 :         fprintf(stderr, "invalid log target \"%s\" (\"%s\")\n", type, dest);
     447           0 :         exit(1);
     448             : }
     449             : 
     450           3 : DEFUN (clear_log_cmdline,
     451             :        clear_log_cmdline_cmd,
     452             :        "clear log cmdline-targets",
     453             :        CLEAR_STR
     454             :        "Logging control\n"
     455             :        "Disable log targets specified at startup by --log option\n")
     456             : {
     457           3 :         zt_file_cmdline.prio_min = ZLOG_DISABLED;
     458           3 :         zlog_file_set_other(&zt_file_cmdline);
     459             : 
     460           3 :         log_cmdline_syslog_lvl = ZLOG_DISABLED;
     461           3 :         zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
     462             :                                              log_cmdline_syslog_lvl));
     463             : 
     464           3 :         log_cmdline_stdout_lvl = ZLOG_DISABLED;
     465           3 :         log_stdout_apply_level();
     466             : 
     467           3 :         return CMD_SUCCESS;
     468             : }
     469             : 
     470           3 : DEFPY (config_log_file,
     471             :        config_log_file_cmd,
     472             :        "log file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
     473             :        "Logging control\n"
     474             :        "Logging to file\n"
     475             :        "Logging filename\n"
     476             :        LOG_LEVEL_DESC)
     477             : {
     478           3 :         int level = log_default_lvl;
     479             : 
     480           3 :         if (levelarg) {
     481           0 :                 level = log_level_match(levelarg);
     482           0 :                 if (level == ZLOG_DISABLED)
     483             :                         return CMD_ERR_NO_MATCH;
     484             :         }
     485           3 :         return set_log_file(&zt_file, vty, filename, level);
     486             : }
     487             : 
     488           0 : DEFUN (no_config_log_file,
     489             :        no_config_log_file_cmd,
     490             :        "no log file [FILENAME [LEVEL]]",
     491             :        NO_STR
     492             :        "Logging control\n"
     493             :        "Cancel logging to file\n"
     494             :        "Logging file name\n"
     495             :        "Logging level\n")
     496             : {
     497           0 :         zt_file.prio_min = ZLOG_DISABLED;
     498           0 :         zlog_file_set_other(&zt_file);
     499           0 :         return CMD_SUCCESS;
     500             : }
     501             : 
     502           0 : DEFPY (config_log_syslog,
     503             :        config_log_syslog_cmd,
     504             :        "log syslog [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
     505             :        "Logging control\n"
     506             :        "Set syslog logging level\n"
     507             :        LOG_LEVEL_DESC)
     508             : {
     509           0 :         int level;
     510             : 
     511           0 :         if (levelarg) {
     512           0 :                 level = log_level_match(levelarg);
     513             : 
     514           0 :                 if (level == ZLOG_DISABLED)
     515             :                         return CMD_ERR_NO_MATCH;
     516             :         } else
     517             :                 level = log_default_lvl;
     518             : 
     519           0 :         log_config_syslog_lvl = level;
     520           0 :         zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
     521             :                                              log_cmdline_syslog_lvl));
     522           0 :         return CMD_SUCCESS;
     523             : }
     524             : 
     525           0 : DEFUN (no_config_log_syslog,
     526             :        no_config_log_syslog_cmd,
     527             :        "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>]",
     528             :        NO_STR
     529             :        "Logging control\n"
     530             :        "Cancel logging to syslog\n"
     531             :        LOG_FACILITY_DESC
     532             :        LOG_LEVEL_DESC)
     533             : {
     534           0 :         log_config_syslog_lvl = ZLOG_DISABLED;
     535           0 :         zlog_syslog_set_prio_min(ZLOG_MAXLVL(log_config_syslog_lvl,
     536             :                                              log_cmdline_syslog_lvl));
     537           0 :         return CMD_SUCCESS;
     538             : }
     539             : 
     540           0 : DEFPY (config_log_facility,
     541             :        config_log_facility_cmd,
     542             :        "log facility <kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>$facilityarg",
     543             :        "Logging control\n"
     544             :        "Facility parameter for syslog messages\n"
     545             :        LOG_FACILITY_DESC)
     546             : {
     547           0 :         int facility = facility_match(facilityarg);
     548             : 
     549           0 :         zlog_syslog_set_facility(facility);
     550           0 :         return CMD_SUCCESS;
     551             : }
     552             : 
     553           0 : DEFUN (no_config_log_facility,
     554             :        no_config_log_facility_cmd,
     555             :        "no log facility [<kern|user|mail|daemon|auth|syslog|lpr|news|uucp|cron|local0|local1|local2|local3|local4|local5|local6|local7>]",
     556             :        NO_STR
     557             :        "Logging control\n"
     558             :        "Reset syslog facility to default (daemon)\n"
     559             :        LOG_FACILITY_DESC)
     560             : {
     561           0 :         zlog_syslog_set_facility(LOG_DAEMON);
     562           0 :         return CMD_SUCCESS;
     563             : }
     564             : 
     565           3 : DEFUN (config_log_record_priority,
     566             :        config_log_record_priority_cmd,
     567             :        "log record-priority",
     568             :        "Logging control\n"
     569             :        "Log the priority of the message within the message\n")
     570             : {
     571           3 :         zt_file.record_priority = true;
     572           3 :         zlog_file_set_other(&zt_file);
     573           3 :         if (!stdout_journald_in_use) {
     574           3 :                 zt_stdout_file.record_priority = true;
     575           3 :                 zlog_file_set_other(&zt_stdout_file);
     576             :         }
     577           3 :         zt_filterfile.parent.record_priority = true;
     578           3 :         zlog_file_set_other(&zt_filterfile.parent);
     579           3 :         return CMD_SUCCESS;
     580             : }
     581             : 
     582           0 : DEFUN (no_config_log_record_priority,
     583             :        no_config_log_record_priority_cmd,
     584             :        "no log record-priority",
     585             :        NO_STR
     586             :        "Logging control\n"
     587             :        "Do not log the priority of the message within the message\n")
     588             : {
     589           0 :         zt_file.record_priority = false;
     590           0 :         zlog_file_set_other(&zt_file);
     591           0 :         if (!stdout_journald_in_use) {
     592           0 :                 zt_stdout_file.record_priority = false;
     593           0 :                 zlog_file_set_other(&zt_stdout_file);
     594             :         }
     595           0 :         zt_filterfile.parent.record_priority = false;
     596           0 :         zlog_file_set_other(&zt_filterfile.parent);
     597           0 :         return CMD_SUCCESS;
     598             : }
     599             : 
     600           3 : DEFPY (config_log_timestamp_precision,
     601             :        config_log_timestamp_precision_cmd,
     602             :        "log timestamp precision (0-6)",
     603             :        "Logging control\n"
     604             :        "Timestamp configuration\n"
     605             :        "Set the timestamp precision\n"
     606             :        "Number of subsecond digits\n")
     607             : {
     608           3 :         zt_file.ts_subsec = precision;
     609           3 :         zlog_file_set_other(&zt_file);
     610           3 :         if (!stdout_journald_in_use) {
     611           3 :                 zt_stdout_file.ts_subsec = precision;
     612           3 :                 zlog_file_set_other(&zt_stdout_file);
     613             :         }
     614           3 :         zt_filterfile.parent.ts_subsec = precision;
     615           3 :         zlog_file_set_other(&zt_filterfile.parent);
     616           3 :         return CMD_SUCCESS;
     617             : }
     618             : 
     619           0 : DEFUN (no_config_log_timestamp_precision,
     620             :        no_config_log_timestamp_precision_cmd,
     621             :        "no log timestamp precision [(0-6)]",
     622             :        NO_STR
     623             :        "Logging control\n"
     624             :        "Timestamp configuration\n"
     625             :        "Reset the timestamp precision to the default value of 0\n"
     626             :        "Number of subsecond digits\n")
     627             : {
     628           0 :         zt_file.ts_subsec = 0;
     629           0 :         zlog_file_set_other(&zt_file);
     630           0 :         if (!stdout_journald_in_use) {
     631           0 :                 zt_stdout_file.ts_subsec = 0;
     632           0 :                 zlog_file_set_other(&zt_stdout_file);
     633             :         }
     634           0 :         zt_filterfile.parent.ts_subsec = 0;
     635           0 :         zlog_file_set_other(&zt_filterfile.parent);
     636           0 :         return CMD_SUCCESS;
     637             : }
     638             : 
     639           0 : DEFPY (config_log_ec,
     640             :        config_log_ec_cmd,
     641             :        "[no] log error-category",
     642             :        NO_STR
     643             :        "Logging control\n"
     644             :        "Prefix log message text with [EC 9999] code\n")
     645             : {
     646           0 :         zlog_set_prefix_ec(!no);
     647           0 :         return CMD_SUCCESS;
     648             : }
     649             : 
     650           0 : DEFPY (config_log_xid,
     651             :        config_log_xid_cmd,
     652             :        "[no] log unique-id",
     653             :        NO_STR
     654             :        "Logging control\n"
     655             :        "Prefix log message text with [XXXXX-XXXXX] identifier\n")
     656             : {
     657           0 :         zlog_set_prefix_xid(!no);
     658           0 :         return CMD_SUCCESS;
     659             : }
     660             : 
     661           0 : DEFPY (config_log_filterfile,
     662             :        config_log_filterfile_cmd,
     663             :        "log filtered-file FILENAME [<emergencies|alerts|critical|errors|warnings|notifications|informational|debugging>$levelarg]",
     664             :        "Logging control\n"
     665             :        "Logging to file with string filter\n"
     666             :        "Logging filename\n"
     667             :        LOG_LEVEL_DESC)
     668             : {
     669           0 :         int level = log_default_lvl;
     670             : 
     671           0 :         if (levelarg) {
     672           0 :                 level = log_level_match(levelarg);
     673           0 :                 if (level == ZLOG_DISABLED)
     674             :                         return CMD_ERR_NO_MATCH;
     675             :         }
     676           0 :         return set_log_file(&zt_filterfile.parent, vty, filename, level);
     677             : }
     678             : 
     679           0 : DEFUN (no_config_log_filterfile,
     680             :        no_config_log_filterfile_cmd,
     681             :        "no log filtered-file [FILENAME [LEVEL]]",
     682             :        NO_STR
     683             :        "Logging control\n"
     684             :        "Cancel logging to file with string filter\n"
     685             :        "Logging file name\n"
     686             :        "Logging level\n")
     687             : {
     688           0 :         zt_filterfile.parent.prio_min = ZLOG_DISABLED;
     689           0 :         zlog_file_set_other(&zt_filterfile.parent);
     690           0 :         return CMD_SUCCESS;
     691             : }
     692             : 
     693           0 : DEFPY (log_filter,
     694             :        log_filter_cmd,
     695             :        "[no] log filter-text WORD$filter",
     696             :        NO_STR
     697             :        "Logging control\n"
     698             :        FILTER_LOG_STR
     699             :        "String to filter by\n")
     700             : {
     701           0 :         int ret = 0;
     702             : 
     703           0 :         if (no)
     704           0 :                 ret = zlog_filter_del(filter);
     705             :         else
     706           0 :                 ret = zlog_filter_add(filter);
     707             : 
     708           0 :         if (ret == 1) {
     709           0 :                 vty_out(vty, "%% filter table full\n");
     710           0 :                 return CMD_WARNING;
     711           0 :         } else if (ret != 0) {
     712           0 :                 vty_out(vty, "%% failed to %s log filter\n",
     713             :                         (no ? "remove" : "apply"));
     714           0 :                 return CMD_WARNING;
     715             :         }
     716             : 
     717           0 :         vty_out(vty, " %s\n", filter);
     718           0 :         return CMD_SUCCESS;
     719             : }
     720             : 
     721             : /* Clear all log filters */
     722           0 : DEFPY (log_filter_clear,
     723             :        log_filter_clear_cmd,
     724             :        "clear log filter-text",
     725             :        CLEAR_STR
     726             :        "Logging control\n"
     727             :        FILTER_LOG_STR)
     728             : {
     729           0 :         zlog_filter_clear();
     730           0 :         return CMD_SUCCESS;
     731             : }
     732             : 
     733             : /* Show log filter */
     734           0 : DEFPY (show_log_filter,
     735             :        show_log_filter_cmd,
     736             :        "show logging filter-text",
     737             :        SHOW_STR
     738             :        "Show current logging configuration\n"
     739             :        FILTER_LOG_STR)
     740             : {
     741           0 :         char log_filters[ZLOG_FILTERS_MAX * (ZLOG_FILTER_LENGTH_MAX + 3)] = "";
     742           0 :         int len = 0;
     743             : 
     744           0 :         len = zlog_filter_dump(log_filters, sizeof(log_filters));
     745             : 
     746           0 :         if (len == -1) {
     747           0 :                 vty_out(vty, "%% failed to get filters\n");
     748           0 :                 return CMD_WARNING;
     749             :         }
     750             : 
     751           0 :         if (len != 0)
     752           0 :                 vty_out(vty, "%s", log_filters);
     753             : 
     754             :         return CMD_SUCCESS;
     755             : }
     756             : 
     757             : /* Enable/disable 'immediate' mode, with no output buffering */
     758           0 : DEFPY (log_immediate_mode,
     759             :        log_immediate_mode_cmd,
     760             :        "[no] log immediate-mode",
     761             :        NO_STR
     762             :        "Logging control\n"
     763             :        "Output immediately, without buffering\n")
     764             : {
     765           0 :         zlog_set_immediate(!no);
     766           0 :         return CMD_SUCCESS;
     767             : }
     768             : 
     769           0 : void log_config_write(struct vty *vty)
     770             : {
     771           0 :         bool show_cmdline_hint = false;
     772             : 
     773           0 :         if (zt_file.prio_min != ZLOG_DISABLED && zt_file.filename) {
     774           0 :                 vty_out(vty, "log file %s", zt_file.filename);
     775             : 
     776           0 :                 if (zt_file.prio_min != log_default_lvl)
     777           0 :                         vty_out(vty, " %s", zlog_priority[zt_file.prio_min]);
     778           0 :                 vty_out(vty, "\n");
     779             :         }
     780             : 
     781           0 :         if (zt_filterfile.parent.prio_min != ZLOG_DISABLED
     782           0 :             && zt_filterfile.parent.filename) {
     783           0 :                 vty_out(vty, "log filtered-file %s",
     784             :                         zt_filterfile.parent.filename);
     785             : 
     786           0 :                 if (zt_filterfile.parent.prio_min != log_default_lvl)
     787           0 :                         vty_out(vty, " %s",
     788           0 :                                 zlog_priority[zt_filterfile.parent.prio_min]);
     789           0 :                 vty_out(vty, "\n");
     790             :         }
     791             : 
     792           0 :         if (log_config_stdout_lvl != ZLOG_DISABLED) {
     793           0 :                 vty_out(vty, "log stdout");
     794             : 
     795           0 :                 if (log_config_stdout_lvl != log_default_lvl)
     796           0 :                         vty_out(vty, " %s",
     797           0 :                                 zlog_priority[log_config_stdout_lvl]);
     798           0 :                 vty_out(vty, "\n");
     799             :         }
     800             : 
     801           0 :         if (log_config_syslog_lvl != ZLOG_DISABLED) {
     802           0 :                 vty_out(vty, "log syslog");
     803             : 
     804           0 :                 if (log_config_syslog_lvl != log_default_lvl)
     805           0 :                         vty_out(vty, " %s",
     806           0 :                                 zlog_priority[log_config_syslog_lvl]);
     807           0 :                 vty_out(vty, "\n");
     808             :         }
     809             : 
     810           0 :         if (log_cmdline_syslog_lvl != ZLOG_DISABLED) {
     811           0 :                 vty_out(vty,
     812             :                         "! \"log syslog %s\" enabled by \"--log\" startup option\n",
     813           0 :                         zlog_priority[log_cmdline_syslog_lvl]);
     814           0 :                 show_cmdline_hint = true;
     815             :         }
     816           0 :         if (log_cmdline_stdout_lvl != ZLOG_DISABLED) {
     817           0 :                 vty_out(vty,
     818             :                         "! \"log stdout %s\" enabled by \"--log\" startup option\n",
     819           0 :                         zlog_priority[log_cmdline_stdout_lvl]);
     820           0 :                 show_cmdline_hint = true;
     821             :         }
     822           0 :         if (zt_file_cmdline.prio_min != ZLOG_DISABLED) {
     823           0 :                 vty_out(vty,
     824             :                         "! \"log file %s %s\" enabled by \"--log\" startup option\n",
     825             :                         zt_file_cmdline.filename,
     826           0 :                         zlog_priority[zt_file_cmdline.prio_min]);
     827           0 :                 show_cmdline_hint = true;
     828             :         }
     829           0 :         if (show_cmdline_hint)
     830           0 :                 vty_out(vty,
     831             :                         "! use \"clear log cmdline-targets\" to remove this target\n");
     832             : 
     833           0 :         if (zlog_syslog_get_facility() != LOG_DAEMON)
     834           0 :                 vty_out(vty, "log facility %s\n",
     835             :                         facility_name(zlog_syslog_get_facility()));
     836             : 
     837           0 :         if (zt_file.record_priority == 1)
     838           0 :                 vty_out(vty, "log record-priority\n");
     839             : 
     840           0 :         if (zt_file.ts_subsec > 0)
     841           0 :                 vty_out(vty, "log timestamp precision %d\n",
     842             :                         zt_file.ts_subsec);
     843             : 
     844           0 :         if (!zlog_get_prefix_ec())
     845           0 :                 vty_out(vty, "no log error-category\n");
     846           0 :         if (!zlog_get_prefix_xid())
     847           0 :                 vty_out(vty, "no log unique-id\n");
     848             : 
     849           0 :         if (logmsgs_with_persist_bt) {
     850           0 :                 struct xrefdata *xrd;
     851           0 :                 struct xrefdata_logmsg *xrdl;
     852             : 
     853           0 :                 vty_out(vty, "!\n");
     854             : 
     855           0 :                 frr_each (xrefdata_uid, &xrefdata_uid, xrd) {
     856           0 :                         if (xrd->xref->type != XREFT_LOGMSG)
     857           0 :                                 continue;
     858             : 
     859           0 :                         xrdl = container_of(xrd, struct xrefdata_logmsg,
     860             :                                             xrefdata);
     861           0 :                         if (xrdl->fl_print_bt & LOGMSG_FLAG_PERSISTENT)
     862           0 :                                 vty_out(vty, "debug unique-id %s backtrace\n",
     863           0 :                                         xrd->uid);
     864             :                 }
     865             :         }
     866           0 : }
     867             : 
     868           3 : static int log_vty_init(const char *progname, const char *protoname,
     869             :                          unsigned short instance, uid_t uid, gid_t gid)
     870             : {
     871           3 :         zlog_progname = progname;
     872           3 :         zlog_protoname = protoname;
     873             : 
     874           3 :         zlog_set_prefix_ec(true);
     875           3 :         zlog_set_prefix_xid(true);
     876             : 
     877           3 :         zlog_filterfile_init(&zt_filterfile);
     878             : 
     879           3 :         if (sd_stdout_is_journal) {
     880           0 :                 stdout_journald_in_use = true;
     881           0 :                 zlog_5424_init(&zt_stdout_journald);
     882           0 :                 zlog_5424_apply_dst(&zt_stdout_journald);
     883             :         } else
     884           3 :                 zlog_file_set_fd(&zt_stdout_file, STDOUT_FILENO);
     885           3 :         return 0;
     886             : }
     887             : 
     888           4 : __attribute__((_CONSTRUCTOR(475))) static void log_vty_preinit(void)
     889             : {
     890           4 :         hook_register(zlog_init, log_vty_init);
     891           4 : }
     892             : 
     893           3 : void log_cmd_init(void)
     894             : {
     895           3 :         install_element(VIEW_NODE, &show_logging_cmd);
     896           3 :         install_element(ENABLE_NODE, &clear_log_cmdline_cmd);
     897             : 
     898           3 :         install_element(CONFIG_NODE, &config_log_stdout_cmd);
     899           3 :         install_element(CONFIG_NODE, &no_config_log_stdout_cmd);
     900           3 :         install_element(CONFIG_NODE, &config_log_monitor_cmd);
     901           3 :         install_element(CONFIG_NODE, &no_config_log_monitor_cmd);
     902           3 :         install_element(CONFIG_NODE, &config_log_file_cmd);
     903           3 :         install_element(CONFIG_NODE, &no_config_log_file_cmd);
     904           3 :         install_element(CONFIG_NODE, &config_log_syslog_cmd);
     905           3 :         install_element(CONFIG_NODE, &no_config_log_syslog_cmd);
     906           3 :         install_element(CONFIG_NODE, &config_log_facility_cmd);
     907           3 :         install_element(CONFIG_NODE, &no_config_log_facility_cmd);
     908           3 :         install_element(CONFIG_NODE, &config_log_record_priority_cmd);
     909           3 :         install_element(CONFIG_NODE, &no_config_log_record_priority_cmd);
     910           3 :         install_element(CONFIG_NODE, &config_log_timestamp_precision_cmd);
     911           3 :         install_element(CONFIG_NODE, &no_config_log_timestamp_precision_cmd);
     912           3 :         install_element(CONFIG_NODE, &config_log_ec_cmd);
     913           3 :         install_element(CONFIG_NODE, &config_log_xid_cmd);
     914             : 
     915           3 :         install_element(VIEW_NODE, &show_log_filter_cmd);
     916           3 :         install_element(CONFIG_NODE, &log_filter_cmd);
     917           3 :         install_element(CONFIG_NODE, &log_filter_clear_cmd);
     918           3 :         install_element(CONFIG_NODE, &config_log_filterfile_cmd);
     919           3 :         install_element(CONFIG_NODE, &no_config_log_filterfile_cmd);
     920           3 :         install_element(CONFIG_NODE, &log_immediate_mode_cmd);
     921             : 
     922           3 :         install_element(ENABLE_NODE, &debug_uid_backtrace_cmd);
     923           3 :         install_element(CONFIG_NODE, &debug_uid_backtrace_cmd);
     924             : 
     925           3 :         log_5424_cmd_init();
     926           3 : }

Generated by: LCOV version v1.16-topotato