lib: add log record-severity command

Record log level using standard syslog severity tags which is understood
by auto-styling/coloring log viewers, etc.

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2025-06-14 15:52:27 +00:00 committed by Christian Hopps
parent f90bd8565b
commit 9db037e2ed
5 changed files with 89 additions and 11 deletions

View file

@ -208,6 +208,18 @@ DEFPY_YANG (config_log_record_priority,
return nb_cli_apply_changes(vty, NULL);
}
DEFPY_YANG (config_log_record_severity,
config_log_record_severity_cmd,
"[no] log record-severity",
NO_STR
"Logging control\n"
"Log the severity of the message within the message\n")
{
nb_cli_enqueue_change(vty, "/frr-logging:logging/record-severity", NB_OP_MODIFY,
no ? "false" : "true");
return nb_cli_apply_changes(vty, NULL);
}
DEFPY_YANG (config_log_timestamp_precision,
config_log_timestamp_precision_cmd,
"log timestamp precision (0-6)",
@ -345,6 +357,7 @@ void log_cli_init(void)
install_element(CONFIG_NODE, &config_log_facility_cmd);
install_element(CONFIG_NODE, &no_config_log_facility_cmd);
install_element(CONFIG_NODE, &config_log_record_priority_cmd);
install_element(CONFIG_NODE, &config_log_record_severity_cmd);
install_element(CONFIG_NODE, &config_log_timestamp_precision_cmd);
install_element(CONFIG_NODE, &no_config_log_timestamp_precision_cmd);
install_element(CONFIG_NODE, &config_log_ec_cmd);
@ -429,6 +442,17 @@ static void logging_record_priority_cli_write(struct vty *vty, const struct lyd_
else if (show_defaults)
vty_out(vty, "no log record-priority\n");
}
static void logging_record_severity_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
{
bool enable = yang_dnode_get_bool(dnode, NULL);
if (enable)
vty_out(vty, "log record-severity\n");
else if (show_defaults)
vty_out(vty, "no log record-severity\n");
}
static void logging_timestamp_precision_cli_write(struct vty *vty, const struct lyd_node *dnode, bool show_defaults)
{
const char *prec = yang_dnode_get_string(dnode, NULL);
@ -482,6 +506,7 @@ const struct frr_yang_module_info frr_logging_cli_info = {
{ .xpath = "/frr-logging:logging/daemon-file/filename", .cbs.cli_show = logging_daemon_file_filename_cli_write },
{ .xpath = "/frr-logging:logging/facility", .cbs.cli_show = logging_facility_cli_write },
{ .xpath = "/frr-logging:logging/record-priority", .cbs.cli_show = logging_record_priority_cli_write },
{ .xpath = "/frr-logging:logging/record-severity", .cbs.cli_show = logging_record_severity_cli_write },
{ .xpath = "/frr-logging:logging/timestamp-precision", .cbs.cli_show = logging_timestamp_precision_cli_write },
{ .xpath = "/frr-logging:logging/error-category", .cbs.cli_show = logging_error_category_cli_write },
{ .xpath = "/frr-logging:logging/unique-id", .cbs.cli_show = logging_unique_id_cli_write },

View file

@ -506,6 +506,29 @@ static int logging_record_priority_modify(struct nb_cb_modify_args *args)
return NB_OK;
}
/*
* XPath: /frr-logging:logging/record-severity
*/
static int logging_record_severity_modify(struct nb_cb_modify_args *args)
{
bool val;
if (args->event != NB_EV_APPLY)
return NB_OK;
val = yang_dnode_get_bool(args->dnode, NULL);
zt_file.record_severity = val;
zlog_file_set_other(&zt_file);
if (!stdout_journald_in_use) {
zt_stdout_file.record_severity = val;
zlog_file_set_other(&zt_stdout_file);
}
zt_filterfile.parent.record_severity = val;
zlog_file_set_other(&zt_filterfile.parent);
return NB_OK;
}
/*
* XPath: /frr-logging:logging/timestamp-precision
@ -729,6 +752,12 @@ const struct frr_yang_module_info frr_logging_nb_info = {
.modify = logging_record_priority_modify,
}
},
{
.xpath = "/frr-logging:logging/record-severity",
.cbs = {
.modify = logging_record_severity_modify,
}
},
{
.xpath = "/frr-logging:logging/timestamp-precision",
.cbs = {

View file

@ -264,6 +264,7 @@ DEFUN_NOSH (show_logging,
vty_out(vty, "Protocol name: %s\n", zlog_protoname);
vty_out(vty, "Record priority: %s\n",
(zt_file.record_priority ? "enabled" : "disabled"));
vty_out(vty, "Record severity: %s\n", (zt_file.record_severity ? "enabled" : "disabled"));
vty_out(vty, "Timestamp precision: %d\n", zt_file.ts_subsec);
hook_call(zlog_cli_show, vty);

View file

@ -35,10 +35,17 @@ struct zlt_fd {
char ts_subsec;
bool record_priority;
bool record_severity;
struct rcu_head_close head_close;
};
static const char *const severity_names[] = {
[LOG_EMERG] = "EMERG: ", [LOG_ALERT] = "ALERT: ", [LOG_CRIT] = "CRIT: ",
[LOG_ERR] = "ERROR: ", [LOG_WARNING] = "WARN: ", [LOG_NOTICE] = "NOTICE: ",
[LOG_INFO] = "INFO: ", [LOG_DEBUG] = "DEBUG: ",
};
static const char * const prionames[] = {
[LOG_EMERG] = "emergencies: ",
[LOG_ALERT] = "alerts: ",
@ -85,6 +92,13 @@ void zlog_fd(struct zlog_target *zt, struct zlog_msg *msgs[], size_t nmsgs)
iovpos++;
if (zte->record_severity) {
iov[iovpos].iov_base = (char *)severity_names[prio];
iov[iovpos].iov_len = strlen(iov[iovpos].iov_base);
iovpos++;
}
if (zte->record_priority) {
iov[iovpos].iov_base = (char *)prionames[prio];
iov[iovpos].iov_len =
@ -127,24 +141,31 @@ static void zlog_fd_sigsafe(struct zlog_target *zt, const char *text,
size_t len)
{
struct zlt_fd *zte = container_of(zt, struct zlt_fd, zt);
struct iovec iov[4];
int fd;
struct iovec iov[5];
int fd, i = 0;
iov[0].iov_base = (char *)prionames[LOG_CRIT];
iov[0].iov_len = zte->record_priority ? strlen(iov[0].iov_base) : 0;
if (zte->record_severity) {
iov[i].iov_base = (char *)severity_names[LOG_CRIT];
iov[i++].iov_len = strlen(iov[0].iov_base);
}
iov[1].iov_base = zlog_prefix;
iov[1].iov_len = zlog_prefixsz;
if (zte->record_priority) {
iov[i].iov_base = (char *)prionames[LOG_CRIT];
iov[i++].iov_len = strlen(iov[0].iov_base);
}
iov[2].iov_base = (char *)text;
iov[2].iov_len = len;
iov[i].iov_base = zlog_prefix;
iov[i++].iov_len = zlog_prefixsz;
iov[3].iov_base = (char *)"\n";
iov[3].iov_len = 1;
iov[i].iov_base = (char *)text;
iov[i++].iov_len = len;
iov[i].iov_base = (char *)"\n";
iov[i++].iov_len = 1;
fd = atomic_load_explicit(&zte->fd, memory_order_relaxed);
writev(fd, iov, array_size(iov));
writev(fd, iov, i);
}
/*
@ -215,6 +236,7 @@ static bool zlog_file_cycle(struct zlog_cfg_file *zcf)
zlt->fd = fd;
zlt->record_priority = zcf->record_priority;
zlt->record_severity = zcf->record_severity;
zlt->ts_subsec = zcf->ts_subsec;
zlt->zt.prio_min = zcf->prio_min;

View file

@ -27,6 +27,7 @@ struct zlog_cfg_file {
int prio_min;
char ts_subsec;
bool record_priority;
bool record_severity;
/* call zlog_file_set_filename/fd() to change this */
char *filename;