From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 1CC5245BC3;
	Thu, 24 Oct 2024 21:09:11 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id A91DE4357E;
	Thu, 24 Oct 2024 21:08:41 +0200 (CEST)
Received: from mail-pl1-f177.google.com (mail-pl1-f177.google.com
 [209.85.214.177])
 by mails.dpdk.org (Postfix) with ESMTP id 31D4243552
 for <dev@dpdk.org>; Thu, 24 Oct 2024 21:08:36 +0200 (CEST)
Received: by mail-pl1-f177.google.com with SMTP id
 d9443c01a7336-20c7edf2872so17686305ad.1
 for <dev@dpdk.org>; Thu, 24 Oct 2024 12:08:36 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1729796915;
 x=1730401715; darn=dpdk.org; 
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:from:to:cc:subject:date
 :message-id:reply-to;
 bh=70OB8KuX7dw5cMRFB0Rl6VfBisz3vI1PLQTN7FJIrzk=;
 b=Xr++mIqEFKU9EIz+SRMOjvDaoRgNTXArgCNuAIaYWrmIZUGGWcxQVohQHiQaPzWbUO
 YVi5nLe11OdSDqhl/OBdm3gqvtnS+1QsgxdP2JRJnjpT5inTXEDFv+rHv3Eb5dYUe3xt
 kyc9BX+Fvg51yW3QjI2dTcLwB6/vncBqM3ib/+1e8S//5T5cTzbH9MOGnnvc2e+JfgaM
 +n6W0HtxeH7opnxflrnOCYAe0H/vPelyHR3VNYseHGQS0XnHhCbPqzyIFf46Mu+uyLAZ
 A3h69ClIzBUUq0tRAimTBpwlH/tsa26+kku2/kxl0Qe+lEN4Nppgu3HY1g8D7zL33LjE
 X8xQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1729796915; x=1730401715;
 h=content-transfer-encoding:mime-version:references:in-reply-to
 :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc
 :subject:date:message-id:reply-to;
 bh=70OB8KuX7dw5cMRFB0Rl6VfBisz3vI1PLQTN7FJIrzk=;
 b=flGalHDFKWXgiWkCriWAehXRtYG7fznJUdUW2VfdGZegYSF5uYtN0PNpHyys4e7zIJ
 aUXFFh0Q+5GVOms3UKQCMK5bpXbVkAL2TsJvjJ+2l26cyaZL3mBlwfvbi6TMhVCj7bYq
 zsHwcWFUkRxrDqFj8x4IxAoKHIszxV+IhWE52R+UIHC9t9WUGqoKJrS0gkl/xaajswZh
 HWF+YxE8nVZkp22tfv+jov3T/ebG1nMOwOZ3pw86GJicVBWVjQZCwd1m3PKrltK3tbV1
 /WvTmGg95oP0PDf6Yw8H3Se5fUf+WSs1KXb7tKn8jk4/RwG4v1UCZU0ivaqXksAcjwo6
 3UiA==
X-Gm-Message-State: AOJu0YyT8PBBkvfdPbFQnIQoxS8ll3IFYbEMzgHAM4rsEQ4dEHQVccLz
 lXRtzDQZk69RO10f1CKxc15yhHVzCfoIWgxQBYC7V7zss92LKpo6meU+3U59M5BbXz2ZkqZA7ox
 q
X-Google-Smtp-Source: AGHT+IE4C27x3Jh4d8LPOPxVJHt9P+aWxuq1qM2SKtJ7vgewDcUrpsMm9H/tro6HG6qCYj+jpWf9AQ==
X-Received: by 2002:a17:902:c403:b0:20c:7e99:3df2 with SMTP id
 d9443c01a7336-20fb89bccb2mr52210635ad.23.1729796915082; 
 Thu, 24 Oct 2024 12:08:35 -0700 (PDT)
Received: from hermes.local (204-195-96-226.wavecable.com. [204.195.96.226])
 by smtp.gmail.com with ESMTPSA id
 d9443c01a7336-20e7f0f364bsm75535385ad.264.2024.10.24.12.08.34
 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);
 Thu, 24 Oct 2024 12:08:34 -0700 (PDT)
From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
 =?UTF-8?q?Morten=20Br=C3=B8rup?= <mb@smartsharesystems.com>,
 Bruce Richardson <bruce.richardson@intel.com>,
 Chengwen Feng <fengchengwen@huawei.com>,
 Tyler Retzlaff <roretzla@linux.microsoft.com>,
 Anatoly Burakov <anatoly.burakov@intel.com>,
 Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Subject: [PATCH v28 07/13] log: rework syslog handling
Date: Thu, 24 Oct 2024 12:02:53 -0700
Message-ID: <20241024190818.172863-8-stephen@networkplumber.org>
X-Mailer: git-send-email 2.45.2
In-Reply-To: <20241024190818.172863-1-stephen@networkplumber.org>
References: <20200814173441.23086-1-stephen@networkplumber.org>
 <20241024190818.172863-1-stephen@networkplumber.org>
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

Refactor how syslog is handled, make it common to Linux and FreeBSD
The syslog facility property is better handled in lib/log
rather than in eal. This also add syslog support to FreeBSD.

Log to syslog only if option is specified.
If no --syslog is given then use console only.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Acked-by: Morten Brørup <mb@smartsharesystems.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Acked-by: Chengwen Feng <fengchengwen@huawei.com>
---
 app/test/test_eal_flags.c                     |  16 +--
 .../freebsd_gsg/freebsd_eal_parameters.rst    |  27 +++++
 .../prog_guide/env_abstraction_layer.rst      |   6 +-
 doc/guides/prog_guide/log_lib.rst             |   5 +-
 lib/eal/common/eal_common_options.c           |  57 ++--------
 lib/eal/common/eal_internal_cfg.h             |   1 -
 lib/eal/freebsd/eal.c                         |   5 +-
 lib/eal/linux/eal.c                           |  12 +--
 lib/eal/windows/eal.c                         |   6 +-
 lib/log/log.c                                 |  45 ++++----
 lib/log/log_freebsd.c                         |  12 ---
 lib/log/log_internal.h                        |  11 +-
 lib/log/log_linux.c                           |  61 -----------
 lib/log/log_private.h                         |  25 +++++
 lib/log/log_syslog.c                          | 100 ++++++++++++++++++
 lib/log/log_windows.c                         |  18 ----
 lib/log/meson.build                           |   6 +-
 lib/log/version.map                           |   2 +-
 18 files changed, 211 insertions(+), 204 deletions(-)
 delete mode 100644 lib/log/log_freebsd.c
 delete mode 100644 lib/log/log_linux.c
 create mode 100644 lib/log/log_private.h
 create mode 100644 lib/log/log_syslog.c
 delete mode 100644 lib/log/log_windows.c

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 71d8dba731..9fcf0d56e6 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -985,12 +985,12 @@ test_misc_flags(void)
 	/* With -v */
 	const char *argv2[] = {prgname, prefix, mp_flag, "-v"};
 	/* With valid --syslog */
-	const char *argv3[] = {prgname, prefix, mp_flag,
-			"--syslog", "syslog"};
-	/* With empty --syslog (should fail) */
+	const char *argv3[] = {prgname, prefix, mp_flag, "--syslog=user"};
+	/* With empty --syslog (now defaults) */
 	const char *argv4[] = {prgname, prefix, mp_flag, "--syslog"};
 	/* With invalid --syslog */
-	const char *argv5[] = {prgname, prefix, mp_flag, "--syslog", "error"};
+	const char *argv5[] = {prgname, prefix, mp_flag, "--syslog=invalid"};
+
 	/* With no-sh-conf, also use no-huge to ensure this test runs on BSD */
 	const char *argv6[] = {prgname, "-m", DEFAULT_MEM_SIZE,
 			no_shconf, nosh_prefix, no_huge};
@@ -1080,15 +1080,15 @@ test_misc_flags(void)
 #endif
 
 	if (launch_proc(argv3) != 0) {
-		printf("Error - process did not run ok with --syslog flag\n");
+		printf("Error - process did not run ok with --syslog=user flag\n");
 		goto fail;
 	}
-	if (launch_proc(argv4) == 0) {
-		printf("Error - process run ok with empty --syslog flag\n");
+	if (launch_proc(argv4) != 0) {
+		printf("Error - process did not run ok with --syslog flag\n");
 		goto fail;
 	}
 	if (launch_proc(argv5) == 0) {
-		printf("Error - process run ok with invalid --syslog flag\n");
+		printf("Error - process run ok with --syslog=invalid flag\n");
 		goto fail;
 	}
 	if (launch_proc(argv7) != 0) {
diff --git a/doc/guides/freebsd_gsg/freebsd_eal_parameters.rst b/doc/guides/freebsd_gsg/freebsd_eal_parameters.rst
index fba467a2ce..9270d9fa3b 100644
--- a/doc/guides/freebsd_gsg/freebsd_eal_parameters.rst
+++ b/doc/guides/freebsd_gsg/freebsd_eal_parameters.rst
@@ -18,3 +18,30 @@ FreeBSD-specific EAL parameters
 -------------------------------
 
 There are currently no FreeBSD-specific EAL command-line parameters available.
+
+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/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst
index b9fac1839d..9bafa30a0e 100644
--- a/doc/guides/prog_guide/env_abstraction_layer.rst
+++ b/doc/guides/prog_guide/env_abstraction_layer.rst
@@ -851,9 +851,9 @@ Signal Safety
   Other functions are not signal safe because they use one or more
   library routines that are not themselves signal safe.
   For example, calling ``rte_panic()`` is not safe in a signal handler
-  because it uses ``rte_log()`` and ``rte_log()`` calls the
-  ``syslog()`` library function which is in the list of
-  signal safe functions in
+  because it uses ``rte_log()`` and ``rte_log()`` may call ``vfprintf()`` or
+  ``syslog()`` library functions which are not in the list of
+  signal safe functions
   `Signal-Safety manual page <https://man7.org/linux/man-pages/man7/signal-safety.7.html>`_.
 
   The set of functions that are expected to be async-signal-safe in DPDK
diff --git a/doc/guides/prog_guide/log_lib.rst b/doc/guides/prog_guide/log_lib.rst
index ff9d1b54a2..c87830ac00 100644
--- a/doc/guides/prog_guide/log_lib.rst
+++ b/doc/guides/prog_guide/log_lib.rst
@@ -5,9 +5,7 @@ Log Library
 ===========
 
 The DPDK Log library provides the logging functionality for other DPDK libraries and drivers.
-By default, in a Linux application, logs are sent to syslog and also to the console.
-On FreeBSD and Windows applications, logs are sent only to the console.
-However, the log function can be overridden by the user to use a different logging mechanism.
+The messages can be sent to one or more sources controlled by the EAL command line options.
 
 Log Levels
 ----------
@@ -59,6 +57,7 @@ For example::
 
 Within an application, the same result can be got using the ``rte_log_set_level_pattern()`` or ``rte_log_set_level_regex()`` APIs.
 
+
 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 eb079a65a9..ca7b702e03 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -6,9 +6,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pthread.h>
-#ifndef RTE_EXEC_ENV_WINDOWS
-#include <syslog.h>
-#endif
 #include <ctype.h>
 #include <limits.h>
 #include <errno.h>
@@ -93,7 +90,9 @@ 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           },
+#ifndef RTE_EXEC_ENV_WINDOWS
+	{OPT_SYSLOG,            2, NULL, OPT_SYSLOG_NUM           },
+#endif
 	{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    },
@@ -349,10 +348,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
 	}
 	internal_cfg->base_virtaddr = 0;
 
-#ifdef LOG_DAEMON
-	internal_cfg->syslog_facility = LOG_DAEMON;
-#endif
-
 	/* if set to NONE, interrupt mode is determined automatically */
 	internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
 	memset(internal_cfg->vfio_vf_token, 0,
@@ -1297,47 +1292,6 @@ eal_parse_lcores(const char *lcores)
 	return ret;
 }
 
-#ifndef RTE_EXEC_ENV_WINDOWS
-static int
-eal_parse_syslog(const char *facility, struct internal_config *conf)
-{
-	int i;
-	static const struct {
-		const char *name;
-		int value;
-	} map[] = {
-		{ "auth", LOG_AUTH },
-		{ "cron", LOG_CRON },
-		{ "daemon", LOG_DAEMON },
-		{ "ftp", LOG_FTP },
-		{ "kern", LOG_KERN },
-		{ "lpr", LOG_LPR },
-		{ "mail", LOG_MAIL },
-		{ "news", LOG_NEWS },
-		{ "syslog", LOG_SYSLOG },
-		{ "user", LOG_USER },
-		{ "uucp", LOG_UUCP },
-		{ "local0", LOG_LOCAL0 },
-		{ "local1", LOG_LOCAL1 },
-		{ "local2", LOG_LOCAL2 },
-		{ "local3", LOG_LOCAL3 },
-		{ "local4", LOG_LOCAL4 },
-		{ "local5", LOG_LOCAL5 },
-		{ "local6", LOG_LOCAL6 },
-		{ "local7", LOG_LOCAL7 },
-		{ NULL, 0 }
-	};
-
-	for (i = 0; map[i].name; i++) {
-		if (!strcmp(facility, map[i].name)) {
-			conf->syslog_facility = map[i].value;
-			return 0;
-		}
-	}
-	return -1;
-}
-#endif
-
 static void
 eal_log_usage(void)
 {
@@ -1663,6 +1617,7 @@ eal_log_level_parse(int argc, char * const argv[])
 
 		switch (opt) {
 		case OPT_LOG_LEVEL_NUM:
+		case OPT_SYSLOG_NUM:
 			if (eal_parse_common_option(opt, optarg, internal_conf) < 0)
 				return -1;
 			break;
@@ -1877,7 +1832,7 @@ eal_parse_common_option(int opt, const char *optarg,
 
 #ifndef RTE_EXEC_ENV_WINDOWS
 	case OPT_SYSLOG_NUM:
-		if (eal_parse_syslog(optarg, conf) < 0) {
+		if (eal_log_syslog(optarg) < 0) {
 			EAL_LOG(ERR, "invalid parameters for --"
 					OPT_SYSLOG);
 			return -1;
@@ -2254,7 +2209,7 @@ eal_common_usage(void)
 	       "  --"OPT_VMWARE_TSC_MAP"    Use VMware TSC map instead of native RDTSC\n"
 	       "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
 #ifndef RTE_EXEC_ENV_WINDOWS
-	       "  --"OPT_SYSLOG"            Set syslog facility\n"
+	       "  --"OPT_SYSLOG"[=<when>]   Enable use of syslog\n"
 #endif
 	       "  --"OPT_LOG_LEVEL"=<level> Set global log level\n"
 	       "  --"OPT_LOG_LEVEL"=<type-match>:<level>\n"
diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h
index 167ec501fa..f53ab8b4aa 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -84,7 +84,6 @@ struct internal_config {
 	/**< true if storing all pages within single files (per-page-size,
 	 * per-node) non-legacy mode only.
 	 */
-	volatile int syslog_facility;	  /**< facility passed to openlog() */
 	/** default interrupt mode for VFIO */
 	volatile enum rte_intr_mode vfio_intr_mode;
 	/** the shared VF token for VFIO-PCI bound PF and VFs devices */
diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c
index 7b974608e4..a609d40ee0 100644
--- a/lib/eal/freebsd/eal.c
+++ b/lib/eal/freebsd/eal.c
@@ -11,7 +11,6 @@
 #include <stdarg.h>
 #include <unistd.h>
 #include <pthread.h>
-#include <syslog.h>
 #include <getopt.h>
 #include <sys/file.h>
 #include <stddef.h>
@@ -392,8 +391,8 @@ eal_parse_args(int argc, char **argv)
 			goto out;
 		}
 
-		/* eal_log_level_parse() already handled this option */
-		if (opt == OPT_LOG_LEVEL_NUM)
+		/* eal_log_level_parse() already handled these */
+		if (opt == OPT_LOG_LEVEL_NUM || opt == OPT_LOG_SYSLOG_NUM)
 			continue;
 
 		ret = eal_parse_common_option(opt, optarg, internal_conf);
diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c
index c53a051405..0c44d0b6e3 100644
--- a/lib/eal/linux/eal.c
+++ b/lib/eal/linux/eal.c
@@ -610,8 +610,8 @@ eal_parse_args(int argc, char **argv)
 			goto out;
 		}
 
-		/* eal_log_level_parse() already handled this option */
-		if (opt == OPT_LOG_LEVEL_NUM)
+		/* eal_log_level_parse() already handled these options */
+		if (opt == OPT_LOG_LEVEL_NUM || opt == OPT_SYSLOG_NUM)
 			continue;
 
 		ret = eal_parse_common_option(opt, optarg, internal_conf);
@@ -1103,13 +1103,7 @@ rte_eal_init(int argc, char **argv)
 #endif
 	}
 
-	if (eal_log_init(program_invocation_short_name,
-			 internal_conf->syslog_facility) < 0) {
-		rte_eal_init_alert("Cannot init logging.");
-		rte_errno = ENOMEM;
-		rte_atomic_store_explicit(&run_once, 0, rte_memory_order_relaxed);
-		return -1;
-	}
+	eal_log_init(program_invocation_short_name);
 
 #ifdef VFIO_PRESENT
 	if (rte_vfio_enable("vfio")) {
diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c
index 93f099a968..cd8420a82c 100644
--- a/lib/eal/windows/eal.c
+++ b/lib/eal/windows/eal.c
@@ -120,8 +120,8 @@ eal_parse_args(int argc, char **argv)
 			return -1;
 		}
 
-		/* eal_log_level_parse() already handled this option */
-		if (opt == OPT_LOG_LEVEL_NUM)
+		/* eal_log_level_parse() already handled these options */
+		if (opt == OPT_LOG_LEVEL_NUM || opt == OPT_SYSLOG_NUM)
 			continue;
 
 		ret = eal_parse_common_option(opt, optarg, internal_conf);
@@ -249,7 +249,7 @@ rte_eal_init(int argc, char **argv)
 	char cpuset[RTE_CPU_AFFINITY_STR_LEN];
 	char thread_name[RTE_THREAD_NAME_SIZE];
 
-	eal_log_init(NULL, 0);
+	eal_log_init(NULL);
 
 	eal_log_level_parse(argc, argv);
 
diff --git a/lib/log/log.c b/lib/log/log.c
index 7416c82b34..feadcd6848 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -2,6 +2,7 @@
  * Copyright(c) 2010-2014 Intel Corporation
  */
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdarg.h>
@@ -11,14 +12,18 @@
 #include <regex.h>
 #include <fnmatch.h>
 #include <sys/queue.h>
+#include <unistd.h>
 
+#include <rte_common.h>
 #include <rte_log.h>
 #include <rte_per_lcore.h>
+
 #ifdef RTE_EXEC_ENV_WINDOWS
 #include <rte_os_shim.h>
 #endif
 
 #include "log_internal.h"
+#include "log_private.h"
 
 struct rte_log_dynamic_type {
 	const char *name;
@@ -54,9 +59,6 @@ TAILQ_HEAD(rte_eal_opt_loglevel_list, rte_eal_opt_loglevel);
 static struct rte_eal_opt_loglevel_list opt_loglevel_list =
 	TAILQ_HEAD_INITIALIZER(opt_loglevel_list);
 
-/* Stream to use for logging if rte_logs.file is NULL */
-static FILE *default_log_stream;
-
 /**
  * This global structure stores some information about the message
  * that is currently being processed by one lcore
@@ -69,8 +71,6 @@ struct log_cur_msg {
  /* per core log */
 static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
 
-/* default logs */
-
 /* Change the stream that will be used by logging system */
 int
 rte_openlog_stream(FILE *f)
@@ -84,17 +84,7 @@ rte_log_get_stream(void)
 {
 	FILE *f = rte_logs.file;
 
-	if (f == NULL) {
-		/*
-		 * Grab the current value of stderr here, rather than
-		 * just initializing default_log_stream to stderr. This
-		 * ensures that we will always use the current value
-		 * of stderr, even if the application closes and
-		 * reopens it.
-		 */
-		return default_log_stream != NULL ? default_log_stream : stderr;
-	}
-	return f;
+	return (f == NULL) ? stderr : f;
 }
 
 /* Set global log level */
@@ -505,12 +495,18 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
 }
 
 /*
- * Called by environment-specific initialization functions.
+ * Called by rte_eal_init
  */
 void
-eal_log_set_default(FILE *default_log)
+eal_log_init(const char *id)
 {
-	default_log_stream = default_log;
+	FILE *logf = NULL;
+
+	if (log_syslog_enabled())
+		logf = log_syslog_open(id);
+
+	if (logf)
+		rte_openlog_stream(logf);
 
 #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG
 	RTE_LOG(NOTICE, EAL,
@@ -524,8 +520,11 @@ eal_log_set_default(FILE *default_log)
 void
 rte_eal_log_cleanup(void)
 {
-	if (default_log_stream) {
-		fclose(default_log_stream);
-		default_log_stream = NULL;
-	}
+	FILE *log_stream = rte_logs.file;
+
+	/* don't close stderr on the application */
+	if (log_stream != NULL)
+		fclose(log_stream);
+
+	rte_logs.file = NULL;
 }
diff --git a/lib/log/log_freebsd.c b/lib/log/log_freebsd.c
deleted file mode 100644
index 698d3c5423..0000000000
--- a/lib/log/log_freebsd.c
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2023 Intel Corporation
- */
-
-#include <rte_common.h>
-#include "log_internal.h"
-
-int
-eal_log_init(__rte_unused const char *id, __rte_unused int facility)
-{
-	return 0;
-}
diff --git a/lib/log/log_internal.h b/lib/log/log_internal.h
index 451629f1c1..3c46328e7b 100644
--- a/lib/log/log_internal.h
+++ b/lib/log/log_internal.h
@@ -14,13 +14,7 @@
  * Initialize the default log stream.
  */
 __rte_internal
-int eal_log_init(const char *id, int facility);
-
-/*
- * Determine where log data is written when no call to rte_openlog_stream.
- */
-__rte_internal
-void eal_log_set_default(FILE *default_log);
+void eal_log_init(const char *id);
 
 /*
  * Save a log option for later.
@@ -30,6 +24,9 @@ int eal_log_save_regexp(const char *regexp, uint32_t level);
 __rte_internal
 int eal_log_save_pattern(const char *pattern, uint32_t level);
 
+__rte_internal
+int eal_log_syslog(const char *name);
+
 /*
  * Convert log level to string.
  */
diff --git a/lib/log/log_linux.c b/lib/log/log_linux.c
deleted file mode 100644
index 2dfb0c974b..0000000000
--- a/lib/log/log_linux.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <syslog.h>
-
-#include <rte_log.h>
-
-#include "log_internal.h"
-
-/*
- * default log function
- */
-static ssize_t
-console_log_write(__rte_unused void *c, const char *buf, size_t size)
-{
-	ssize_t ret;
-
-	/* write on stderr */
-	ret = fwrite(buf, 1, size, stderr);
-	fflush(stderr);
-
-	/* 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 ret;
-}
-
-static int
-console_log_close(__rte_unused void *c)
-{
-	closelog();
-	return 0;
-}
-
-static cookie_io_functions_t console_log_func = {
-	.write = console_log_write,
-	.close = console_log_close,
-};
-
-/*
- * set the log to default function, called during eal init process,
- * once memzones are available.
- */
-int
-eal_log_init(const char *id, int facility)
-{
-	FILE *log_stream;
-
-	log_stream = fopencookie(NULL, "w+", console_log_func);
-	if (log_stream == NULL)
-		return -1;
-
-	openlog(id, LOG_NDELAY | LOG_PID, facility);
-
-	eal_log_set_default(log_stream);
-
-	return 0;
-}
diff --git a/lib/log/log_private.h b/lib/log/log_private.h
new file mode 100644
index 0000000000..bf87b43f7e
--- /dev/null
+++ b/lib/log/log_private.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+#ifndef LOG_PRIVATE_H
+#define LOG_PRIVATE_H
+
+/* Defined in limits.h on Linux */
+#ifndef LINE_MAX
+#define LINE_MAX	2048 /* _POSIX2_LINE_MAX */
+#endif
+
+#ifdef RTE_EXEC_ENV_WINDOWS
+static inline bool log_syslog_enabled(void)
+{
+	return false;
+}
+static inline FILE *log_syslog_open(const char *id __rte_unused)
+{
+	return NULL;
+}
+#else
+bool log_syslog_enabled(void);
+FILE *log_syslog_open(const char *id);
+#endif
+
+#endif /* LOG_PRIVATE_H */
diff --git a/lib/log/log_syslog.c b/lib/log/log_syslog.c
new file mode 100644
index 0000000000..7d29e3a00f
--- /dev/null
+++ b/lib/log/log_syslog.c
@@ -0,0 +1,100 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2014 Intel Corporation
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <syslog.h>
+
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include "log_internal.h"
+#include "log_private.h"
+
+static int log_facility;
+
+static const struct {
+	const char *name;
+	int value;
+} facilitys[] = {
+	{ "auth", LOG_AUTH },
+	{ "cron", LOG_CRON },
+	{ "daemon", LOG_DAEMON },
+	{ "ftp", LOG_FTP },
+	{ "kern", LOG_KERN },
+	{ "lpr", LOG_LPR },
+	{ "mail", LOG_MAIL },
+	{ "news", LOG_NEWS },
+	{ "syslog", LOG_SYSLOG },
+	{ "user", LOG_USER },
+	{ "uucp", LOG_UUCP },
+	{ "local0", LOG_LOCAL0 },
+	{ "local1", LOG_LOCAL1 },
+	{ "local2", LOG_LOCAL2 },
+	{ "local3", LOG_LOCAL3 },
+	{ "local4", LOG_LOCAL4 },
+	{ "local5", LOG_LOCAL5 },
+	{ "local6", LOG_LOCAL6 },
+	{ "local7", LOG_LOCAL7 },
+};
+
+int
+eal_log_syslog(const char *name)
+{
+	unsigned int i;
+
+	for (i = 0; i < RTE_DIM(facilitys); i++) {
+		if (!strcmp(name, facilitys[i].name)) {
+			log_facility = facilitys[i].value;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/* syslog is enabled if facility is set */
+bool log_syslog_enabled(void)
+{
+	return log_facility != 0; /* LOG_KERN is 0 */
+}
+
+/*
+ * default log function
+ */
+static ssize_t
+log_syslog_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
+log_syslog_close(__rte_unused void *c)
+{
+	closelog();
+	return 0;
+}
+
+static cookie_io_functions_t log_syslog_func = {
+	.write = log_syslog_write,
+	.close = log_syslog_close,
+};
+
+
+FILE *
+log_syslog_open(const char *id)
+{
+	int option = LOG_CONS | LOG_NDELAY | LOG_PID | LOG_PERROR;
+
+	openlog(id, option, log_facility);
+
+	/* redirect other log messages to syslog as well */
+	return fopencookie(NULL, "w", log_syslog_func);
+}
diff --git a/lib/log/log_windows.c b/lib/log/log_windows.c
deleted file mode 100644
index a6a0889550..0000000000
--- a/lib/log/log_windows.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017-2018 Intel Corporation
- */
-
-#include <rte_common.h>
-#include <rte_log.h>
-#include "log_internal.h"
-
-/* set the log to default function, called during eal init process. */
-int
-eal_log_init(__rte_unused const char *id, __rte_unused int facility)
-{
-	rte_openlog_stream(stderr);
-
-	eal_log_set_default(stderr);
-
-	return 0;
-}
diff --git a/lib/log/meson.build b/lib/log/meson.build
index 0d4319b36f..160cf34f50 100644
--- a/lib/log/meson.build
+++ b/lib/log/meson.build
@@ -4,6 +4,10 @@
 includes += global_inc
 sources = files(
         'log.c',
-        'log_' + exec_env + '.c',
 )
+
+if not is_windows
+    sources += files('log_syslog.c')
+endif
+
 headers = files('rte_log.h')
diff --git a/lib/log/version.map b/lib/log/version.map
index 19d7f9cdb6..1637fba3b9 100644
--- a/lib/log/version.map
+++ b/lib/log/version.map
@@ -29,6 +29,6 @@ INTERNAL {
 	eal_log_level2str;
 	eal_log_save_pattern;
 	eal_log_save_regexp;
-	eal_log_set_default;
+	eal_log_syslog; # WINDOWS_NO_EXPORT
 	rte_eal_log_cleanup;
 };
-- 
2.45.2