[PATCH v12 11/14] log: add optional support of syslog
Stephen Hemminger
stephen at networkplumber.org
Mon Mar 25 21:47:08 CET 2024
Log to syslog only if option is specified. And if syslog is used
then normally only log to syslog, don't duplicate output.
Also enables syslog support on FreeBSD.
Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
doc/guides/linux_gsg/linux_eal_parameters.rst | 27 -----
doc/guides/prog_guide/log_lib.rst | 17 +++
lib/eal/common/eal_common_options.c | 2 +-
lib/log/log.c | 101 ++++++++++++++++--
4 files changed, 111 insertions(+), 36 deletions(-)
diff --git a/doc/guides/linux_gsg/linux_eal_parameters.rst b/doc/guides/linux_gsg/linux_eal_parameters.rst
index ea8f381391..d86f94d8a8 100644
--- a/doc/guides/linux_gsg/linux_eal_parameters.rst
+++ b/doc/guides/linux_gsg/linux_eal_parameters.rst
@@ -108,30 +108,3 @@ Memory-related options
* ``--match-allocations``
Free hugepages back to system exactly as they were originally allocated.
-
-Other options
-~~~~~~~~~~~~~
-
-* ``--syslog <syslog facility>``
-
- Set syslog facility. Valid syslog facilities are::
-
- auth
- cron
- daemon
- ftp
- kern
- lpr
- mail
- news
- syslog
- user
- uucp
- local0
- local1
- local2
- local3
- local4
- local5
- local6
- local7
diff --git a/doc/guides/prog_guide/log_lib.rst b/doc/guides/prog_guide/log_lib.rst
index 504eefe1d2..abaedc7212 100644
--- a/doc/guides/prog_guide/log_lib.rst
+++ b/doc/guides/prog_guide/log_lib.rst
@@ -83,6 +83,23 @@ To prefix all console messages with ISO format time the syntax is::
/path/to/app --log-timestamp=iso
+Log output
+~~~~~~~~~~
+
+If desired, messages can be redirected to syslog (on Linux and FreeBSD) with the ``--syslog``
+option. There are three possible settings for this option:
+
+*always*
+ Redirect all log output to syslog.
+
+*auto*
+ Use console if it is a terminal, and use syslog if is not.
+
+*both*
+ Print to both console and syslog.
+
+If ``--syslog`` option is not specified, then only console (stderr) will be used.
+
Using Logging APIs to Generate Log Messages
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index aa1faad45c..6f0fd151c1 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -91,7 +91,7 @@ eal_long_options[] = {
{OPT_PROC_TYPE, 1, NULL, OPT_PROC_TYPE_NUM },
{OPT_SOCKET_MEM, 1, NULL, OPT_SOCKET_MEM_NUM },
{OPT_SOCKET_LIMIT, 1, NULL, OPT_SOCKET_LIMIT_NUM },
- {OPT_SYSLOG, 1, NULL, OPT_SYSLOG_NUM },
+ {OPT_SYSLOG, 2, NULL, OPT_SYSLOG_NUM },
{OPT_VDEV, 1, NULL, OPT_VDEV_NUM },
{OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
{OPT_VFIO_VF_TOKEN, 1, NULL, OPT_VFIO_VF_TOKEN_NUM },
diff --git a/lib/log/log.c b/lib/log/log.c
index 2dca91306e..d8974c66db 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -13,15 +13,17 @@
#include <sys/queue.h>
#include <unistd.h>
+#ifdef RTE_EXEC_ENV_WINDOWS
+#include <rte_os_shim.h>
+#else
+#include <syslog.h>
+#endif
+
#include <rte_log.h>
#include <rte_per_lcore.h>
#include "log_internal.h"
-#ifdef RTE_EXEC_ENV_WINDOWS
-#include <rte_os_shim.h>
-#endif
-
struct rte_log_dynamic_type {
const char *name;
uint32_t loglevel;
@@ -36,14 +38,25 @@ enum eal_log_time_format {
EAL_LOG_TIMESTAMP_ISO,
};
+enum eal_log_syslog {
+ EAL_LOG_SYSLOG_NONE = 0, /* do not use syslog */
+ EAL_LOG_SYSLOG_AUTO, /* use syslog only if not a terminal */
+ EAL_LOG_SYSLOG_ALWAYS, /* always use syslog */
+ EAL_LOG_SYSLOG_BOTH, /* log to both syslog and stderr */
+};
+
typedef int (*log_print_t)(FILE *f, uint32_t level, const char *fmt, va_list ap);
static int log_print(FILE *f, uint32_t level, const char *format, va_list ap);
+
/** The rte_log structure. */
static struct rte_logs {
uint32_t type; /**< Bitfield with enabled logs. */
uint32_t level; /**< Log level. */
FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */
+#ifndef RTE_EXEC_ENV_WINDOWS
+ enum eal_log_syslog syslog_opt;
+#endif
log_print_t print_func;
enum eal_log_time_format time_format;
@@ -532,9 +545,23 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
/* Placeholder */
int
-eal_log_syslog(const char *mode __rte_unused)
+eal_log_syslog(const char *str)
{
+#ifdef RTE_EXEC_ENV_WINDOWS
+ RTE_SET_USED(str);
return -1;
+#else
+ if (str == NULL || strcmp(str, "auto") == 0)
+ /* log to syslog only if stderr is not a terminal */
+ rte_logs.syslog_opt = EAL_LOG_SYSLOG_AUTO;
+ else if (strcmp(str, "both") == 0)
+ rte_logs.syslog_opt = EAL_LOG_SYSLOG_BOTH;
+ else if (strcmp(str, "always") == 0)
+ rte_logs.syslog_opt = EAL_LOG_SYSLOG_ALWAYS;
+ else
+ return -1;
+ return 0;
+#endif
}
/* Set the log timestamp format */
@@ -706,17 +733,75 @@ log_print_with_timestamp(FILE *f, uint32_t level,
return log_print(f, level, format, ap);
}
+#ifndef RTE_EXEC_ENV_WINDOWS
/*
- * Called by rte_eal_init
+ * wrapper for log stream to put messages into syslog
+ * useful for cases like:
+ * rte_hex_dump(rte_get_log_stream(), ...)
*/
-void
-eal_log_init(const char *id __rte_unused)
+static ssize_t
+syslog_log_write(__rte_unused void *c, const char *buf, size_t size)
+{
+ /* Syslog error levels are from 0 to 7, so subtract 1 to convert */
+ syslog(rte_log_cur_msg_loglevel() - 1, "%.*s", (int)size, buf);
+ return size;
+}
+
+static int
+syslog_log_close(__rte_unused void *c)
{
+ closelog();
+ return 0;
+}
+
+static cookie_io_functions_t syslog_log_func = {
+ .write = syslog_log_write,
+ .close = syslog_log_close,
+};
+#endif
+
+
+/* Choose how log output is directed */
+static void
+log_output_selection(const char *id)
+{
+ RTE_SET_USED(id);
+
+#ifndef RTE_EXEC_ENV_WINDOWS
+ bool is_terminal = isatty(STDERR_FILENO);
+
+ if (!(rte_logs.syslog_opt == EAL_LOG_SYSLOG_NONE ||
+ (rte_logs.syslog_opt == EAL_LOG_SYSLOG_AUTO && is_terminal))) {
+ int flags = LOG_NDELAY | LOG_PID;
+
+#ifdef LOG_PERROR
+ if (rte_logs.syslog_opt == EAL_LOG_SYSLOG_BOTH)
+ flags |= LOG_PERROR;
+#endif
+ openlog(id, flags, is_terminal ? LOG_USER : LOG_DAEMON);
+
+ /* redirect other log messages to syslog as well */
+ FILE *log_stream = fopencookie(NULL, "w", syslog_log_func);
+ if (log_stream != NULL)
+ default_log_stream = log_stream;
+ return;
+ }
+#endif
if (rte_logs.time_format != EAL_LOG_TIMESTAMP_NONE)
rte_logs.print_func = log_print_with_timestamp;
+}
+/*
+ * Called by rte_eal_init
+ */
+void
+eal_log_init(const char *id)
+{
+ rte_logs.print_func = log_print;
default_log_stream = stderr;
+ log_output_selection(id);
+
#if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
RTE_LOG(NOTICE, EAL,
"Debug dataplane logs available - lower performance\n");
--
2.43.0
More information about the dev
mailing list