From patchwork Fri Nov 8 08:47:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148138 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 59D6545CB1; Fri, 8 Nov 2024 09:52:04 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 4A63942EE9; Fri, 8 Nov 2024 09:52:04 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id 7218442EDB for ; Fri, 8 Nov 2024 09:52:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055922; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/ou8lGZfUYRcDDarmldeautbdhYxmilhRMlkIsbj51M=; b=Em2jiE4KwmyxytKjO4t1sfUomoe4p6+Q7R/POMa3UQl+iiPdcK4DQp3YmwcGn7Ps8yzX8D RDUuzUt4X8AnB4JXmFOg1I+/NFBGB06O/LS3JCGKHQ9bODUdR1AfD4s6ZBj0uE5FCVcOv3 lkzcC3joc+knF275tN9kVFslgfEd01w= Received: from mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-205-tr1W4JsVMK-WlWsca7WynA-1; Fri, 08 Nov 2024 03:48:16 -0500 X-MC-Unique: tr1W4JsVMK-WlWsca7WynA-1 X-Mimecast-MFC-AGG-ID: tr1W4JsVMK-WlWsca7WynA Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D286D1955E84; Fri, 8 Nov 2024 08:48:14 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9F4851955F3D; Fri, 8 Nov 2024 08:48:11 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , Tyler Retzlaff , Dmitry Kozlyuk , =?utf-8?q?Morten_Br=C3=B8rup?= , Bruce Richardson , Chengwen Feng Subject: [PATCH v32 01/12] eal/windows: align getopt to FreeBSD Date: Fri, 8 Nov 2024 09:47:50 +0100 Message-ID: <20241108084802.2942435-2-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: cMMfAsLUtXjLmccbTYV5M0iFzpL-IAkL0heND0nbVoU_1731055695 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger Having different prototypes on different platforms can lead to lots of unnecessary workarounds. It looks like the version of getopt used from windows was based on an older out of date version from FreeBSD. This patch changes getopt, getopt_long, etc to have the same const attributes as Linux and FreeBSD. The changes are derived from the current FreeBSD version of getopt_long. Signed-off-by: Stephen Hemminger Acked-by: Tyler Retzlaff Acked-by: Dmitry Kozlyuk Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- lib/eal/windows/getopt.c | 23 ++++++++++++----------- lib/eal/windows/include/getopt.h | 8 ++++---- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/eal/windows/getopt.c b/lib/eal/windows/getopt.c index a1f51c6c23..50ff71b930 100644 --- a/lib/eal/windows/getopt.c +++ b/lib/eal/windows/getopt.c @@ -20,7 +20,7 @@ #include #include -const char *optarg; /* argument associated with option */ +char *optarg; /* argument associated with option */ int opterr = 1; /* if error message should be printed */ int optind = 1; /* index into parent argv vector */ int optopt = '?'; /* character checked for validity */ @@ -39,9 +39,9 @@ static void pass(const char *a) {(void) a; } #define BADARG ((*options == ':') ? (int)':' : (int)'?') #define INORDER 1 -#define EMSG "" +static char EMSG[] = ""; -static const char *place = EMSG; /* option letter processing */ +static char *place = EMSG; /* option letter processing */ /* XXX: set optreset to 1 rather than these two */ static int nonopt_start = -1; /* first non option argument (for permute) */ @@ -80,7 +80,7 @@ gcd(int a, int b) */ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, - char **nargv) + char * const *nargv) { int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; char *swap; @@ -101,11 +101,12 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, pos -= nnonopts; else pos += nopts; + swap = nargv[pos]; /* LINTED const cast */ - ((char **) nargv)[pos] = nargv[cstart]; + ((char **)(uintptr_t)nargv)[pos] = nargv[cstart]; /* LINTED const cast */ - ((char **)nargv)[cstart] = swap; + ((char **)(uintptr_t)nargv)[cstart] = swap; } } } @@ -116,7 +117,7 @@ permute_args(int panonopt_start, int panonopt_end, int opt_end, * Returns -1 if short_too is set and the option does not match long_options. */ static int -parse_long_options(char **nargv, const char *options, +parse_long_options(char * const *nargv, const char *options, const struct option *long_options, int *idx, int short_too) { const char *current_argv; @@ -236,7 +237,7 @@ parse_long_options(char **nargv, const char *options, * Parse argc/argv argument vector. Called by user level routines. */ static int -getopt_internal(int nargc, char **nargv, const char *options, +getopt_internal(int nargc, char *const nargv[], const char *options, const struct option *long_options, int *idx, int flags) { char *oli; /* option letter list index */ @@ -434,7 +435,7 @@ getopt_internal(int nargc, char **nargv, const char *options, * Parse argc/argv argument vector. */ int -getopt(int nargc, char *nargv[], const char *options) +getopt(int nargc, char *const nargv[], const char *options) { return getopt_internal(nargc, nargv, options, NULL, NULL, FLAG_PERMUTE); @@ -445,7 +446,7 @@ getopt(int nargc, char *nargv[], const char *options) * Parse argc/argv argument vector. */ int -getopt_long(int nargc, char *nargv[], const char *options, +getopt_long(int nargc, char *const nargv[], const char *options, const struct option *long_options, int *idx) { @@ -458,7 +459,7 @@ getopt_long(int nargc, char *nargv[], const char *options, * Parse argc/argv argument vector. */ int -getopt_long_only(int nargc, char *nargv[], const char *options, +getopt_long_only(int nargc, char *const nargv[], const char *options, const struct option *long_options, int *idx) { diff --git a/lib/eal/windows/include/getopt.h b/lib/eal/windows/include/getopt.h index 6f57af454b..e4cf6873cb 100644 --- a/lib/eal/windows/include/getopt.h +++ b/lib/eal/windows/include/getopt.h @@ -44,7 +44,7 @@ /** argument to current option, or NULL if it has none */ -extern const char *optarg; +extern char *optarg; /** Current position in arg string. Starts from 1. * Setting to 0 resets state. */ @@ -80,14 +80,14 @@ struct option { }; /** Compat: getopt */ -int getopt(int argc, char *argv[], const char *options); +int getopt(int argc, char *const argv[], const char *options); /** Compat: getopt_long */ -int getopt_long(int argc, char *argv[], const char *options, +int getopt_long(int argc, char *const argv[], const char *options, const struct option *longopts, int *longindex); /** Compat: getopt_long_only */ -int getopt_long_only(int nargc, char *argv[], const char *options, +int getopt_long_only(int nargc, char *const argv[], const char *options, const struct option *long_options, int *idx); From patchwork Fri Nov 8 08:47:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148130 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id C549C45CB1; Fri, 8 Nov 2024 09:48:43 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id B22E242F1B; Fri, 8 Nov 2024 09:48:43 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id 2C95A42EE9 for ; Fri, 8 Nov 2024 09:48:42 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055721; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e9ti2ZK4TAmg9dt959eN2Mw2L1lvSaYARbBFG7XXnAk=; b=bGMnLOJFDTOky+4R0gS8V1FmKpWRayEbsTMnebX7A/Q7y5uKSk5U4nLp++3w2nzUDZ8hs9 AM4hgRZGas6ep+12iqUd3eLXsqTj8D66tL0MP3RpXdMFFAxcxyJu8auzH+QfxB9vH8VqkJ Z3GmY0lFHAhxKXUFEEKKZx70/FN+3tA= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-683-In0yHAuJOumzlan0YwEq9g-1; Fri, 08 Nov 2024 03:48:37 -0500 X-MC-Unique: In0yHAuJOumzlan0YwEq9g-1 X-Mimecast-MFC-AGG-ID: In0yHAuJOumzlan0YwEq9g Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3FE971945115; Fri, 8 Nov 2024 08:48:36 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7C6D21956054; Fri, 8 Nov 2024 08:48:33 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , Bruce Richardson , Chengwen Feng Subject: [PATCH v32 05/12] eal: improve exit output log Date: Fri, 8 Nov 2024 09:47:54 +0100 Message-ID: <20241108084802.2942435-6-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: R4e0XO9ukhZDabjQ1MvuKrer4Ag3sMDQdBILJDX_nOY_1731055716 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger The rte_exit() output format confuses the timestamp and coloring options. Change it to use be a single line with proper prefix. Before: [ 0.006481] EAL: Error - exiting with code: 1 Cause: [ 0.006489] Cannot init EAL: Permission denied After: [ 0.006238] EAL: Error - exiting with code: 1 [ 0.006250] EAL: Cannot init EAL: Permission denied Signed-off-by: Stephen Hemminger Acked-by: Tyler Retzlaff Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- lib/eal/common/eal_common_debug.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/eal/common/eal_common_debug.c b/lib/eal/common/eal_common_debug.c index 3e77995896..bcfcd6df6f 100644 --- a/lib/eal/common/eal_common_debug.c +++ b/lib/eal/common/eal_common_debug.c @@ -36,15 +36,13 @@ rte_exit(int exit_code, const char *format, ...) va_list ap; if (exit_code != 0) - RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n" - " Cause: ", exit_code); + EAL_LOG(CRIT, "Error - exiting with code: %d", exit_code); va_start(ap, format); rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap); va_end(ap); if (rte_eal_cleanup() != 0 && rte_errno != EALREADY) - EAL_LOG(CRIT, - "EAL could not release all resources"); + EAL_LOG(CRIT, "EAL could not release all resources"); exit(exit_code); } From patchwork Fri Nov 8 08:47:55 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148137 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6BFF045CB1; Fri, 8 Nov 2024 09:49:45 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id AE26E42FCD; Fri, 8 Nov 2024 09:49:30 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id 7B2D6432CA for ; Fri, 8 Nov 2024 09:49:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055768; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lhKqtYpBQffqRZhSH6I7tyy+ilxZ0FqynFcrnyai4i8=; b=f2rBpBvk28QeGlvUyJMPRCuyUg8tZFIqMWQjRyESEJWwLQz5neqb1vswYDLr1XBfj9lv0e EA5/j5NWPScGyTcA0vdAOh8t99Ue7F/hZmMcFtCV+Xn0wUzX3P3P2DTPgCtdxVYA6IzSnJ 7vfzIiiIjdE+goi5isLWK17oQd4Yzwo= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-171-ZdeWGv-FMaivUd3kIW27uQ-1; Fri, 08 Nov 2024 03:48:44 -0500 X-MC-Unique: ZdeWGv-FMaivUd3kIW27uQ-1 X-Mimecast-MFC-AGG-ID: ZdeWGv-FMaivUd3kIW27uQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 3A21819560BE; Fri, 8 Nov 2024 08:48:42 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 250D0300019E; Fri, 8 Nov 2024 08:48:38 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , =?utf-8?q?Morten_Br?= =?utf-8?q?=C3=B8rup?= , Bruce Richardson , Chengwen Feng , Tyler Retzlaff , Anatoly Burakov , Dmitry Kozlyuk Subject: [PATCH v32 06/12] log: rework syslog handling Date: Fri, 8 Nov 2024 09:47:55 +0100 Message-ID: <20241108084802.2942435-7-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: p1hgWPpksjMmJtR-H6t3nRQM5qfNmNqG8sPTJu9cAGg_1731055722 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger 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 adds syslog support to FreeBSD. Log to syslog only if option is specified. If no --syslog is given then use only standard error. Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- 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 | 6 +- doc/guides/rel_notes/release_24_11.rst | 6 + lib/eal/common/eal_common_options.c | 57 +-------- lib/eal/common/eal_internal_cfg.h | 1 - lib/eal/freebsd/eal.c | 1 - lib/eal/linux/eal.c | 8 +- lib/eal/windows/eal.c | 2 +- lib/log/log.c | 43 ++++--- lib/log/log_freebsd.c | 12 -- lib/log/log_internal.h | 11 +- lib/log/log_linux.c | 61 ---------- lib/log/log_private.h | 27 +++++ lib/log/log_syslog.c | 108 ++++++++++++++++++ lib/log/log_windows.c | 18 --- lib/log/meson.build | 6 +- lib/log/version.map | 2 +- 19 files changed, 220 insertions(+), 198 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 `` + + 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 272aeeb4ba..04214a05b2 100644 --- a/doc/guides/prog_guide/env_abstraction_layer.rst +++ b/doc/guides/prog_guide/env_abstraction_layer.rst @@ -884,9 +884,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 `_. 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..9cee75b88c 100644 --- a/doc/guides/prog_guide/log_lib.rst +++ b/doc/guides/prog_guide/log_lib.rst @@ -5,9 +5,9 @@ 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. +By default, logs are sent only to standard error output of the process. +The syslog EAL option can be used to redirect to the stystem logger on Linux and FreeBSD. +In addition, the log can be redirected to a different stdio file stream. Log Levels ---------- diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index d93343fd52..f27d283fab 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -114,6 +114,12 @@ New Features (and vice versa); freeing the same pointer twice in the same routine; freeing an object that was not created by allocation; etc. +* **Updated logging library** + + * The syslog option has changed. + By default, messages are no longer sent to syslog unless the ``--syslog`` option is specified. + Syslog is also supported on FreeBSD (but not on Windows). + * **Updated Marvell cnxk mempool driver.** * Added mempool driver support for CN20K SoC. diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index ab6cf8bebf..9f4feb2611 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -6,9 +6,6 @@ #include #include #include -#ifndef RTE_EXEC_ENV_WINDOWS -#include -#endif #include #include #include @@ -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) { @@ -1645,6 +1599,7 @@ eal_option_is_log(int opt) { switch (opt) { case OPT_LOG_LEVEL_NUM: + case OPT_SYSLOG_NUM: return true; default: return false; @@ -1887,7 +1842,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; @@ -2264,7 +2219,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"[=] Enable use of syslog (and optionally set facility)\n" #endif " --"OPT_LOG_LEVEL"= Set global log level\n" " --"OPT_LOG_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 c84983ac3f..e7fd4f141e 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c index 3915cdb838..c321ea87f3 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c @@ -1104,13 +1104,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 a3eb15ce00..b948c52670 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -251,7 +251,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); /* parse log options as early as possible */ eal_parse_log_options(argc, argv); diff --git a/lib/log/log.c b/lib/log/log.c index 255f757d94..a5cae1f950 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -2,6 +2,7 @@ * Copyright(c) 2010-2014 Intel Corporation */ +#include #include #include #include @@ -12,10 +13,12 @@ #include #include +#include #include #include #include "log_internal.h" +#include "log_private.h" #ifdef RTE_EXEC_ENV_WINDOWS #define strdup _strdup @@ -55,9 +58,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 @@ -70,8 +70,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) @@ -85,17 +83,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 */ @@ -506,12 +494,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, @@ -525,8 +519,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 -#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 -#include -#include - -#include - -#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..d5a8bf271a --- /dev/null +++ b/lib/log/log_private.h @@ -0,0 +1,27 @@ +/* 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..6b34831bf3 --- /dev/null +++ b/lib/log/log_syslog.c @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include +#include +#include +#include +#include + +#include +#include + +#include "log_internal.h" +#include "log_private.h" + +static int log_facility; + +/* + * Usable list of facilities + * Skip kern, mark, and security + */ +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; + + if (name == NULL) { + log_facility = LOG_DAEMON; + return 0; + } + + 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 -#include -#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; }; From patchwork Fri Nov 8 08:47:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148131 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id B1D6D45CB1; Fri, 8 Nov 2024 09:49:01 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 59A27432B8; Fri, 8 Nov 2024 09:48:54 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id AB9E142FAF for ; Fri, 8 Nov 2024 09:48:52 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055732; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zfwPgpVgkcVDTcnH3B3p1uFHJ4NUqtWC0eBY6zCHtQU=; b=QIJqVuoN2L4Ja1AjwLAx1N7z3t/BeEtT6hJXkfKjsgLg1/PH64zy7zVWnMiQwYjB+Wc/ph IOste/qJeZ7RjrmDAk0OEy/Kx79v1XhqGC+H1fCllYm2wnArqAPpSVacu4i0mvgC6hP37t s7YHHoTnlZPRJRwdgUEVUU1fsUKDjjk= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-387-FibXrxEDN9SWWzhC5pKcng-1; Fri, 08 Nov 2024 03:48:49 -0500 X-MC-Unique: FibXrxEDN9SWWzhC5pKcng-1 X-Mimecast-MFC-AGG-ID: FibXrxEDN9SWWzhC5pKcng Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 824B8197731E; Fri, 8 Nov 2024 08:48:47 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id EE3411953880; Fri, 8 Nov 2024 08:48:44 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , Bruce Richardson , Chengwen Feng , Dmitry Kozlyuk Subject: [PATCH v32 07/12] eal: initialize log before everything else Date: Fri, 8 Nov 2024 09:47:56 +0100 Message-ID: <20241108084802.2942435-8-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 5P2cytnd-qOEG9Au1uSQJVGtuOOZWaneSd4tbZNyYAI_1731055727 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger In order for all log messages (including CPU mismatch) to come out through the logging library, it must be initialized as early in rte_eal_init() as possible on all platforms. Where it was done before was likely historical, based on the support of non-OS isolated CPU's which required a shared memory buffer. That support was dropped before DPDK was publicly released. Signed-off-by: Stephen Hemminger Acked-by: Tyler Retzlaff Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- doc/guides/rel_notes/release_24_11.rst | 2 ++ lib/eal/freebsd/eal.c | 13 ++++++++++--- lib/eal/linux/eal.c | 14 +++++++++----- lib/eal/windows/eal.c | 10 +++++++--- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index f27d283fab..3853af2798 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -116,6 +116,8 @@ New Features * **Updated logging library** + * The log subsystem is initialized earlier in startup so all messages go through the library. + * The syslog option has changed. By default, messages are no longer sent to syslog unless the ``--syslog`` option is specified. Syslog is also supported on FreeBSD (but not on Windows). diff --git a/lib/eal/freebsd/eal.c b/lib/eal/freebsd/eal.c index e7fd4f141e..a96bbf5836 100644 --- a/lib/eal/freebsd/eal.c +++ b/lib/eal/freebsd/eal.c @@ -53,6 +53,7 @@ #include "eal_options.h" #include "eal_memcfg.h" #include "eal_trace.h" +#include "log_internal.h" #define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL) @@ -547,6 +548,15 @@ rte_eal_init(int argc, char **argv) bool has_phys_addr; enum rte_iova_mode iova_mode; + /* setup log as early as possible */ + if (eal_parse_log_options(argc, argv) < 0) { + rte_eal_init_alert("invalid log arguments."); + rte_errno = EINVAL; + return -1; + } + + eal_log_init(getprogname()); + /* checks if the machine is adequate */ if (!rte_cpu_is_supported()) { rte_eal_init_alert("unsupported cpu type."); @@ -573,9 +583,6 @@ rte_eal_init(int argc, char **argv) /* clone argv to report out later in telemetry */ eal_save_args(argc, argv); - /* parse log options as early as possible */ - eal_parse_log_options(argc, argv); - if (rte_eal_cpu_init() < 0) { rte_eal_init_alert("Cannot detect lcores."); rte_errno = ENOTSUP; diff --git a/lib/eal/linux/eal.c b/lib/eal/linux/eal.c index c321ea87f3..a6220524a4 100644 --- a/lib/eal/linux/eal.c +++ b/lib/eal/linux/eal.c @@ -927,6 +927,15 @@ rte_eal_init(int argc, char **argv) struct internal_config *internal_conf = eal_get_internal_configuration(); + /* setup log as early as possible */ + if (eal_parse_log_options(argc, argv) < 0) { + rte_eal_init_alert("invalid log arguments."); + rte_errno = EINVAL; + return -1; + } + + eal_log_init(program_invocation_short_name); + /* checks if the machine is adequate */ if (!rte_cpu_is_supported()) { rte_eal_init_alert("unsupported cpu type."); @@ -950,9 +959,6 @@ rte_eal_init(int argc, char **argv) eal_reset_internal_config(internal_conf); - /* parse log options as early as possible */ - eal_parse_log_options(argc, argv); - /* clone argv to report out later in telemetry */ eal_save_args(argc, argv); @@ -1104,8 +1110,6 @@ rte_eal_init(int argc, char **argv) #endif } - eal_log_init(program_invocation_short_name); - #ifdef VFIO_PRESENT if (rte_vfio_enable("vfio")) { rte_eal_init_alert("Cannot init VFIO"); diff --git a/lib/eal/windows/eal.c b/lib/eal/windows/eal.c index b948c52670..5cdc053a02 100644 --- a/lib/eal/windows/eal.c +++ b/lib/eal/windows/eal.c @@ -251,10 +251,14 @@ 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); + /* setup log as early as possible */ + if (eal_parse_log_options(argc, argv) < 0) { + rte_eal_init_alert("invalid log arguments."); + rte_errno = EINVAL; + return -1; + } - /* parse log options as early as possible */ - eal_parse_log_options(argc, argv); + eal_log_init(NULL); if (eal_create_cpu_map() < 0) { rte_eal_init_alert("Cannot discover CPU and NUMA."); From patchwork Fri Nov 8 08:47:57 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148132 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 7B7BC45CB1; Fri, 8 Nov 2024 09:49:08 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7282F42F6B; Fri, 8 Nov 2024 09:49:00 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id C619542F0A for ; Fri, 8 Nov 2024 09:48:58 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055738; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/w/rAmifDHQSdwaFK6acc80npKF7BH08C494oqg1LB4=; b=T1Xdvva4XV0ucAhdkyXKYtcNHQhCY9Lz97XanR3fUsAw56wupVz5Tx83NyN7ZmaFV4Ug0f 4XZ6z+dees2k5/vYqRPyFxxqaXMBBjbUztWbGC5m7UVf+/KBJEwWm4nLuyvYGF0j/SjCRR kXYQbLbmFGIJcHIJS/nHPRRXOC2I0io= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-558-g-7kJYTbNk2I3_vDg6LFZg-1; Fri, 08 Nov 2024 03:48:53 -0500 X-MC-Unique: g-7kJYTbNk2I3_vDg6LFZg-1 X-Mimecast-MFC-AGG-ID: g-7kJYTbNk2I3_vDg6LFZg Received: from mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.12]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 35035194511A; Fri, 8 Nov 2024 08:48:52 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-03.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 55FBB195E480; Fri, 8 Nov 2024 08:48:50 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , =?utf-8?q?Morten_Br?= =?utf-8?q?=C3=B8rup?= , Bruce Richardson , Chengwen Feng Subject: [PATCH v32 08/12] log: add hook for printing log messages Date: Fri, 8 Nov 2024 09:47:57 +0100 Message-ID: <20241108084802.2942435-9-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.12 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: EN6BkgoBeME_6lgFtwxs02idHCUC02lU0krLNGUXZtk_1731055732 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger This is useful for when decorating log output for console or journal. Provide basic version in this patch. Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- lib/log/log.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/log/log.c b/lib/log/log.c index a5cae1f950..dbff223108 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -29,16 +29,21 @@ struct rte_log_dynamic_type { uint32_t loglevel; }; +/* Note: same as vfprintf() */ +typedef int (*log_print_t)(FILE *f, const char *fmt, 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. */ + log_print_t print_func; size_t dynamic_types_len; struct rte_log_dynamic_type *dynamic_types; } rte_logs = { .type = UINT32_MAX, .level = RTE_LOG_DEBUG, + .print_func = vfprintf, }; struct rte_eal_opt_loglevel { @@ -75,6 +80,7 @@ int rte_openlog_stream(FILE *f) { rte_logs.file = f; + rte_logs.print_func = vfprintf; return 0; } @@ -471,7 +477,7 @@ rte_vlog(uint32_t level, uint32_t logtype, const char *format, va_list ap) RTE_PER_LCORE(log_cur_msg).loglevel = level; RTE_PER_LCORE(log_cur_msg).logtype = logtype; - ret = vfprintf(f, format, ap); + ret = (*rte_logs.print_func)(f, format, ap); fflush(f); return ret; } From patchwork Fri Nov 8 08:47:58 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148133 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id AD4A145CB1; Fri, 8 Nov 2024 09:49:15 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id BB5EC42F37; Fri, 8 Nov 2024 09:49:03 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id 9D49442F0A for ; Fri, 8 Nov 2024 09:49:02 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055742; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=ws0M/A8aXvRUOWvH4TkEXLY8sWq9oY84LVbArh8QPGI=; b=M+yt5BftywY+K78+k9xcPAm1vawD/tMMEbGiNgB87EI2+5oDUGP++haSieD3VimO8FZidF qEyYE6GdBVMTzY9rF6LFiUHGB/yuEIInj/t/HiDFGrp7eJi8aRqn5X44k4NKb5LUJK8eLr U5OHTpvUMknNZuhHFL0p3/nrW5rk2Zg= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-590-4qW7qY9bO9Gn-RvflrMUpg-1; Fri, 08 Nov 2024 03:48:59 -0500 X-MC-Unique: 4qW7qY9bO9Gn-RvflrMUpg-1 X-Mimecast-MFC-AGG-ID: 4qW7qY9bO9Gn-RvflrMUpg Received: from mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.15]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 20115196C438; Fri, 8 Nov 2024 08:48:57 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 07FFE195607C; Fri, 8 Nov 2024 08:48:54 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , =?utf-8?q?Morten_Br?= =?utf-8?q?=C3=B8rup?= , Bruce Richardson , Tyler Retzlaff , Dmitry Kozlyuk Subject: [PATCH v32 09/12] log: add timestamp option Date: Fri, 8 Nov 2024 09:47:58 +0100 Message-ID: <20241108084802.2942435-10-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.15 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: uknOglAKp_ls1ZTh8NC96bIPze8yMoufbXQxXwywRrE_1731055737 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger When debugging driver or startup issues, it is useful to have a timestamp on each message printed. The messages in syslog already have a timestamp, but often syslog is not available during testing. There are multiple timestamp formats similar to Linux dmesg. The default is time relative since startup (when first step of logging initialization is done by constructor). Other alternative formats are delta, ctime, reltime and iso formats. Example: $ dpdk-testpmd --log-timestamp -- -i [ 0.008610] EAL: Detected CPU lcores: 8 [ 0.008634] EAL: Detected NUMA nodes: 1 [ 0.008792] EAL: Detected static linkage of DPDK [ 0.010620] EAL: Multi-process socket /var/run/dpdk/rte/mp_socket [ 0.012618] EAL: Selected IOVA mode 'VA' [ 0.016675] testpmd: No probed ethernet devices Interactive-mode selected Note: Windows does not have localtime_r but it does have a similar function that can be used instead. Add it to rte_os_shim.h. Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup Acked-by: Bruce Richardson --- app/test/test_eal_flags.c | 24 +++ doc/guides/prog_guide/log_lib.rst | 28 +++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eal/common/eal_common_options.c | 14 +- lib/eal/common/eal_options.h | 2 + lib/eal/windows/include/rte_os_shim.h | 10 ++ lib/log/log.c | 13 +- lib/log/log_internal.h | 9 + lib/log/log_private.h | 6 + lib/log/log_timestamp.c | 240 +++++++++++++++++++++++++ lib/log/meson.build | 1 + lib/log/version.map | 1 + 12 files changed, 344 insertions(+), 6 deletions(-) create mode 100644 lib/log/log_timestamp.c diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c index 9fcf0d56e6..1a062fe0e8 100644 --- a/app/test/test_eal_flags.c +++ b/app/test/test_eal_flags.c @@ -1055,6 +1055,18 @@ test_misc_flags(void) const char * const argv22[] = {prgname, prefix, mp_flag, "--huge-worker-stack=512"}; + /* Try running with --log-timestamp */ + const char * const argv23[] = {prgname, prefix, mp_flag, + "--log-timestamp" }; + + /* Try running with --log-timestamp=iso */ + const char * const argv24[] = {prgname, prefix, mp_flag, + "--log-timestamp=iso" }; + + /* Try running with invalid timestamp */ + const char * const argv25[] = {prgname, prefix, mp_flag, + "--log-timestamp=invalid" }; + /* run all tests also applicable to FreeBSD first */ if (launch_proc(argv0) == 0) { @@ -1162,6 +1174,18 @@ test_misc_flags(void) printf("Error - process did not run ok with --huge-worker-stack=size parameter\n"); goto fail; } + if (launch_proc(argv23) != 0) { + printf("Error - process did not run ok with --log-timestamp parameter\n"); + goto fail; + } + if (launch_proc(argv24) != 0) { + printf("Error - process did not run ok with --log-timestamp=iso parameter\n"); + goto fail; + } + if (launch_proc(argv25) == 0) { + printf("Error - process did run ok with --log-timestamp=invalid parameter\n"); + goto fail; + } rmdir(hugepath_dir3); rmdir(hugepath_dir2); diff --git a/doc/guides/prog_guide/log_lib.rst b/doc/guides/prog_guide/log_lib.rst index 9cee75b88c..a2e95317f5 100644 --- a/doc/guides/prog_guide/log_lib.rst +++ b/doc/guides/prog_guide/log_lib.rst @@ -110,3 +110,31 @@ Throughout the cfgfile library, all logging calls are therefore of the form: CFG_LOG(ERR, "invalid comment characters %c", params->comment_character); + +Log timestamp +~~~~~~~~~~~~~ + +An optional timestamp can be added before each message by adding the ``--log-timestamp`` option. +For example:: + + /path/to/app --log-level=lib.*:debug --log-timestamp + +Multiple alternative timestamp formats are available: + +.. csv-table:: Log time stamp format + :header: "Format", "Description", "Example" + :widths: 6, 30, 32 + + "ctime", "Unix ctime", "``[Wed Mar 20 07:26:12 2024]``" + "delta", "Offset since last", "``[< 3.162373>]``" + "reltime", "Seconds since last or time if minute changed", "``[ +3.001791]`` or ``[Mar20 07:26:12]``" + "iso", "ISO-8601", "``[2024-03-20T07:26:12−07:00]``" + +To prefix all console messages with ISO format time the syntax is:: + + /path/to/app --log-timestamp=iso + +.. note:: + + Timestamp option has no effect if using syslog + because the ``syslog()`` service already does timestamping internally. diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 3853af2798..d1226c78d1 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -122,6 +122,8 @@ New Features By default, messages are no longer sent to syslog unless the ``--syslog`` option is specified. Syslog is also supported on FreeBSD (but not on Windows). + * Log messages can be timestamped with ``--log-timestamp`` option. + * **Updated Marvell cnxk mempool driver.** * Added mempool driver support for CN20K SoC. diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index 9f4feb2611..7de6a25e62 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -74,6 +74,7 @@ eal_long_options[] = { {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, + {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, {OPT_TRACE_DIR, 1, NULL, OPT_TRACE_DIR_NUM }, {OPT_TRACE_BUF_SIZE, 1, NULL, OPT_TRACE_BUF_SIZE_NUM }, @@ -1599,6 +1600,7 @@ eal_option_is_log(int opt) { switch (opt) { case OPT_LOG_LEVEL_NUM: + case OPT_LOG_TIMESTAMP_NUM: case OPT_SYSLOG_NUM: return true; default: @@ -1850,7 +1852,7 @@ eal_parse_common_option(int opt, const char *optarg, break; #endif - case OPT_LOG_LEVEL_NUM: { + case OPT_LOG_LEVEL_NUM: if (eal_parse_log_level(optarg) < 0) { EAL_LOG(ERR, "invalid parameters for --" @@ -1858,7 +1860,14 @@ eal_parse_common_option(int opt, const char *optarg, return -1; } break; - } + + case OPT_LOG_TIMESTAMP_NUM: + if (eal_log_timestamp(optarg) < 0) { + EAL_LOG(ERR, "invalid parameters for --" + OPT_LOG_TIMESTAMP); + return -1; + } + break; #ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM: { @@ -2225,6 +2234,7 @@ eal_common_usage(void) " --"OPT_LOG_LEVEL"=:\n" " Set specific log level\n" " --"OPT_LOG_LEVEL"=help Show log types and levels\n" + " --"OPT_LOG_TIMESTAMP"[=] Timestamp log output\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_TRACE"=\n" " Enable trace based on regular expression trace name.\n" diff --git a/lib/eal/common/eal_options.h b/lib/eal/common/eal_options.h index 06ba023c5a..a1b52ae694 100644 --- a/lib/eal/common/eal_options.h +++ b/lib/eal/common/eal_options.h @@ -35,6 +35,8 @@ enum { OPT_LCORES_NUM, #define OPT_LOG_LEVEL "log-level" OPT_LOG_LEVEL_NUM, +#define OPT_LOG_TIMESTAMP "log-timestamp" + OPT_LOG_TIMESTAMP_NUM, #define OPT_TRACE "trace" OPT_TRACE_NUM, #define OPT_TRACE_DIR "trace-dir" diff --git a/lib/eal/windows/include/rte_os_shim.h b/lib/eal/windows/include/rte_os_shim.h index eda8113662..665c9ac93b 100644 --- a/lib/eal/windows/include/rte_os_shim.h +++ b/lib/eal/windows/include/rte_os_shim.h @@ -110,4 +110,14 @@ rte_clock_gettime(clockid_t clock_id, struct timespec *tp) } #define clock_gettime(clock_id, tp) rte_clock_gettime(clock_id, tp) +static inline struct tm * +rte_localtime_r(const time_t *timep, struct tm *result) +{ + if (localtime_s(result, timep) == 0) + return result; + else + return NULL; +} +#define localtime_r(timep, result) rte_localtime_r(timep, result) + #endif /* _RTE_OS_SHIM_ */ diff --git a/lib/log/log.c b/lib/log/log.c index dbff223108..854d77887b 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -17,13 +17,13 @@ #include #include -#include "log_internal.h" -#include "log_private.h" - #ifdef RTE_EXEC_ENV_WINDOWS -#define strdup _strdup +#include #endif +#include "log_internal.h" +#include "log_private.h" + struct rte_log_dynamic_type { const char *name; uint32_t loglevel; @@ -513,6 +513,11 @@ eal_log_init(const char *id) if (logf) rte_openlog_stream(logf); + if (log_timestamp_enabled()) + rte_logs.print_func = log_print_with_timestamp; + else + rte_logs.print_func = vfprintf; + #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL, "Debug dataplane logs available - lower performance\n"); diff --git a/lib/log/log_internal.h b/lib/log/log_internal.h index 3c46328e7b..7c7d44eed2 100644 --- a/lib/log/log_internal.h +++ b/lib/log/log_internal.h @@ -5,8 +5,10 @@ #ifndef LOG_INTERNAL_H #define LOG_INTERNAL_H +#include #include #include +#include #include @@ -39,4 +41,11 @@ const char *eal_log_level2str(uint32_t level); __rte_internal void rte_eal_log_cleanup(void); +/* + * Add timestamp to console logs + */ +__rte_internal +int eal_log_timestamp(const char *fmt); + + #endif /* LOG_INTERNAL_H */ diff --git a/lib/log/log_private.h b/lib/log/log_private.h index d5a8bf271a..5da9c9b438 100644 --- a/lib/log/log_private.h +++ b/lib/log/log_private.h @@ -24,4 +24,10 @@ bool log_syslog_enabled(void); FILE *log_syslog_open(const char *id); #endif +bool log_timestamp_enabled(void); +ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); + +__rte_format_printf(2, 0) +int log_print_with_timestamp(FILE *f, const char *format, va_list ap); + #endif /* LOG_PRIVATE_H */ diff --git a/lib/log/log_timestamp.c b/lib/log/log_timestamp.c new file mode 100644 index 0000000000..b4b0bca6a8 --- /dev/null +++ b/lib/log/log_timestamp.c @@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef RTE_EXEC_ENV_WINDOWS +#include +#endif + +#include "log_internal.h" +#include "log_private.h" + +#ifndef NS_PER_SEC +#define NS_PER_SEC 1E9 +#endif + +static enum { + LOG_TIMESTAMP_NONE = 0, + LOG_TIMESTAMP_TIME, /* time since start */ + LOG_TIMESTAMP_DELTA, /* time since last message */ + LOG_TIMESTAMP_RELTIME, /* relative time since last message */ + LOG_TIMESTAMP_CTIME, /* Unix standard time format */ + LOG_TIMESTAMP_ISO, /* ISO8601 time format */ +} log_time_format; + +static struct { + struct timespec started; /* when log was initialized */ + RTE_ATOMIC(uint64_t) last_monotonic; + RTE_ATOMIC(uint64_t) last_realtime; +} log_time; + +/* Set the log timestamp format */ +int +eal_log_timestamp(const char *str) +{ + if (str == NULL) + log_time_format = LOG_TIMESTAMP_TIME; + else if (strcmp(str, "notime") == 0) + log_time_format = LOG_TIMESTAMP_NONE; + else if (strcmp(str, "reltime") == 0) + log_time_format = LOG_TIMESTAMP_RELTIME; + else if (strcmp(str, "delta") == 0) + log_time_format = LOG_TIMESTAMP_DELTA; + else if (strcmp(str, "ctime") == 0) + log_time_format = LOG_TIMESTAMP_CTIME; + else if (strcmp(str, "iso") == 0) + log_time_format = LOG_TIMESTAMP_ISO; + else + return -1; + + return 0; +} + +bool +log_timestamp_enabled(void) +{ + return log_time_format != LOG_TIMESTAMP_NONE; +} + +/* Subtract two timespec values and handle wraparound */ +static struct timespec +timespec_sub(const struct timespec *t0, const struct timespec *t1) +{ + struct timespec ts; + + ts.tv_sec = t0->tv_sec - t1->tv_sec; + ts.tv_nsec = t0->tv_nsec - t1->tv_nsec; + if (ts.tv_nsec < 0) { + ts.tv_sec--; + ts.tv_nsec += 1000000000L; + } + return ts; +} + +/* + * Format current timespec into ISO8601 format. + * Surprisingly, can't just use strftime() for this; + * since want microseconds and the timezone offset format differs. + */ +static ssize_t +format_iso8601(char *tsbuf, size_t tsbuflen, const struct timespec *now) +{ + struct tm *tm, tbuf; + char dbuf[64]; /* "2024-05-01T22:11:00" */ + char zbuf[16] = { }; /* "+0800" */ + + tm = localtime_r(&now->tv_sec, &tbuf); + + /* make "2024-05-01T22:11:00,123456+0100" */ + if (strftime(dbuf, sizeof(dbuf), "%Y-%m-%dT%H:%M:%S", tm) == 0) + return 0; + + /* convert timezone to +hhmm */ + if (strftime(zbuf, sizeof(zbuf), "%z", tm) == 0) + return 0; + + /* the result for strftime is "+hhmm" but ISO wants "+hh:mm" */ + return snprintf(tsbuf, tsbuflen, "%s,%06lu%.3s:%.2s", + dbuf, now->tv_nsec / 1000u, + zbuf, zbuf + 3); +} + +/* + * Format a timestamp which shows time between messages. + */ +static ssize_t +format_delta(char *tsbuf, size_t tsbuflen, const struct timespec *now) +{ + struct timespec delta; + uint64_t ns = rte_timespec_to_ns(now); + uint64_t previous; + + previous = rte_atomic_exchange_explicit(&log_time.last_monotonic, + ns, rte_memory_order_seq_cst); + delta = rte_ns_to_timespec(ns - previous); + + return snprintf(tsbuf, tsbuflen, "<%6lu.%06lu>", + (unsigned long)delta.tv_sec, + (unsigned long)delta.tv_nsec / 1000u); +} + +/* + * Make a timestamp where if the minute, hour or day has + * changed from the last message, then print abbreviated + * "Month day hour:minute" format. + * Otherwise print delta from last printed message as +sec.usec + */ +static ssize_t +format_reltime(char *tsbuf, size_t tsbuflen, const struct timespec *now) +{ + struct tm *tm, *last_tm, tbuf1, tbuf2; + time_t last_sec; + uint64_t ns = rte_timespec_to_ns(now); + uint64_t previous; + + tm = localtime_r(&now->tv_sec, &tbuf1); + + previous = rte_atomic_exchange_explicit(&log_time.last_realtime, + ns, rte_memory_order_seq_cst); + last_sec = previous / NS_PER_SEC; + last_tm = localtime_r(&last_sec, &tbuf2); + if (tm->tm_min == last_tm->tm_min && + tm->tm_hour == last_tm->tm_hour && + tm->tm_yday == last_tm->tm_yday) { + struct timespec elapsed; + + elapsed = rte_ns_to_timespec(ns - previous); + + return snprintf(tsbuf, tsbuflen, "+%3lu.%06lu", + (unsigned long)elapsed.tv_sec, + (unsigned long)elapsed.tv_nsec / 1000u); + } else { + return strftime(tsbuf, tsbuflen, "%b%d %H:%M", tm); + } +} + +/* Format up a timestamp based on current format */ +ssize_t +log_timestamp(char *tsbuf, size_t tsbuflen) +{ + struct timespec now, delta; + + switch (log_time_format) { + case LOG_TIMESTAMP_NONE: + return 0; + + case LOG_TIMESTAMP_TIME: + if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) + return 0; + + delta = timespec_sub(&now, &log_time.started); + + return snprintf(tsbuf, tsbuflen, "%6lu.%06lu", + (unsigned long)delta.tv_sec, + (unsigned long)delta.tv_nsec / 1000u); + + case LOG_TIMESTAMP_DELTA: + if (clock_gettime(CLOCK_MONOTONIC, &now) < 0) + return 0; + + return format_delta(tsbuf, tsbuflen, &now); + + case LOG_TIMESTAMP_RELTIME: + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + return 0; + + return format_reltime(tsbuf, tsbuflen, &now); + + case LOG_TIMESTAMP_CTIME: + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + return 0; + + /* trncate to remove newline from ctime result */ + return snprintf(tsbuf, tsbuflen, "%.24s", ctime(&now.tv_sec)); + + case LOG_TIMESTAMP_ISO: + if (clock_gettime(CLOCK_REALTIME, &now) < 0) + return 0; + + return format_iso8601(tsbuf, tsbuflen, &now); + } + + return 0; +} + +/* print timestamp before message */ +int +log_print_with_timestamp(FILE *f, const char *format, va_list ap) +{ + char tsbuf[128]; + char msgbuf[LINE_MAX]; + + if (log_timestamp(tsbuf, sizeof(tsbuf)) > 0) { + vsnprintf(msgbuf, sizeof(msgbuf), format, ap); + return fprintf(f, "[%s] %s", tsbuf, msgbuf); + } + + /* fall back when timestamp is unavailable */ + return vfprintf(f, format, ap); +} + +RTE_INIT_PRIO(log_timestamp_init, LOG) +{ + struct timespec now; + + clock_gettime(CLOCK_MONOTONIC, &now); + log_time.started = now; + rte_atomic_store_explicit(&log_time.last_monotonic, rte_timespec_to_ns(&now), + rte_memory_order_seq_cst); +} diff --git a/lib/log/meson.build b/lib/log/meson.build index 160cf34f50..4ac232786e 100644 --- a/lib/log/meson.build +++ b/lib/log/meson.build @@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_timestamp.c', ) if not is_windows diff --git a/lib/log/version.map b/lib/log/version.map index 1637fba3b9..8be6907840 100644 --- a/lib/log/version.map +++ b/lib/log/version.map @@ -30,5 +30,6 @@ INTERNAL { eal_log_save_pattern; eal_log_save_regexp; eal_log_syslog; # WINDOWS_NO_EXPORT + eal_log_timestamp; rte_eal_log_cleanup; }; From patchwork Fri Nov 8 08:47:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148134 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 63DD145CB1; Fri, 8 Nov 2024 09:49:24 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5383C43009; Fri, 8 Nov 2024 09:49:08 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id BF53642F0A for ; Fri, 8 Nov 2024 09:49:06 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055746; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iUQwYOnRFdWw4KH8yAR3de6WRYvUItAJpj2+hsuAdEI=; b=W1qBqGOD9PLjwEPgcfSqjGsOHKgod2n/+99AVRvDzUXi+3e8IZafCsQMLbXFl8wINIehr0 V9/nsglvHvRbtn8QbgzRfEClL04QOUjzypyAcCUE/81+33iTd2zNZNfrr7oIywZ+pi+pzU IhfdYhMh35GCG6mOnLwUcvBRBtQVrwE= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-274-9eRg3FItO3KFa9AYcOemnQ-1; Fri, 08 Nov 2024 03:49:02 -0500 X-MC-Unique: 9eRg3FItO3KFa9AYcOemnQ-1 X-Mimecast-MFC-AGG-ID: 9eRg3FItO3KFa9AYcOemnQ Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 95CCE1955F34; Fri, 8 Nov 2024 08:49:01 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id DF1FF300019E; Fri, 8 Nov 2024 08:48:59 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , =?utf-8?q?Morten_Br?= =?utf-8?q?=C3=B8rup?= , Bruce Richardson Subject: [PATCH v32 10/12] log: support systemd journal Date: Fri, 8 Nov 2024 09:47:59 +0100 Message-ID: <20241108084802.2942435-11-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: jWHyeql2yFLgMvIktcnFrlFJvcT8ivCd3J0lgMhTDM8_1731055741 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger If DPDK application is being run as a systemd service, then it can use the journal protocol which allows putting more information in the log such as priority and other information. The use of journal protocol is automatically detected and handled. Rather than having a dependency on libsystemd, just use the protocol directly as defined in: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup Acked-by: Bruce Richardson --- doc/guides/rel_notes/release_24_11.rst | 4 + lib/log/log.c | 31 +++-- lib/log/log_internal.h | 3 + lib/log/log_journal.c | 153 +++++++++++++++++++++++++ lib/log/log_private.h | 16 +++ lib/log/meson.build | 4 + lib/log/version.map | 1 + 7 files changed, 200 insertions(+), 12 deletions(-) create mode 100644 lib/log/log_journal.c diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index d1226c78d1..341606f541 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -118,6 +118,10 @@ New Features * The log subsystem is initialized earlier in startup so all messages go through the library. + * If the application is a systemd service and the log output is being sent to standard error + then DPDK will switch to journal native protocol. + This allows the more data such as severity to be sent. + * The syslog option has changed. By default, messages are no longer sent to syslog unless the ``--syslog`` option is specified. Syslog is also supported on FreeBSD (but not on Windows). diff --git a/lib/log/log.c b/lib/log/log.c index 854d77887b..0974adc81f 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -505,18 +505,25 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...) void eal_log_init(const char *id) { - FILE *logf = NULL; - - if (log_syslog_enabled()) - logf = log_syslog_open(id); - - if (logf) - rte_openlog_stream(logf); - - if (log_timestamp_enabled()) - rte_logs.print_func = log_print_with_timestamp; - else - rte_logs.print_func = vfprintf; + /* If user has already set a log stream, then use it. */ + if (rte_logs.file == NULL) { + FILE *logf = NULL; + + /* if stderr is associated with systemd environment */ + if (log_journal_enabled()) + logf = log_journal_open(id); + /* If --syslog option was passed */ + else if (log_syslog_enabled()) + logf = log_syslog_open(id); + + /* if either syslog or journal is used, then no special handling */ + if (logf) + rte_openlog_stream(logf); + else if (log_timestamp_enabled()) + rte_logs.print_func = log_print_with_timestamp; + else + rte_logs.print_func = vfprintf; + } #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL, diff --git a/lib/log/log_internal.h b/lib/log/log_internal.h index 7c7d44eed2..82fdc21ac2 100644 --- a/lib/log/log_internal.h +++ b/lib/log/log_internal.h @@ -29,6 +29,9 @@ int eal_log_save_pattern(const char *pattern, uint32_t level); __rte_internal int eal_log_syslog(const char *name); +__rte_internal +int eal_log_journal(const char *opt); + /* * Convert log level to string. */ diff --git a/lib/log/log_journal.c b/lib/log/log_journal.c new file mode 100644 index 0000000000..e9b3aa5640 --- /dev/null +++ b/lib/log/log_journal.c @@ -0,0 +1,153 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "log_private.h" + +/* + * Send structured message using journal protocol + * See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ + * + * Uses writev() to ensure that whole log message is in one datagram + */ +static int +journal_send(int fd, const char *buf, size_t len) +{ + struct iovec iov[4]; + unsigned int n = 0; + int priority = rte_log_cur_msg_loglevel() - 1; + char msg[] = "MESSAGE="; + char newline = '\n'; + char pbuf[32]; /* "PRIORITY=N\n" */ + + iov[n].iov_base = msg; + iov[n++].iov_len = strlen(msg); + + iov[n].iov_base = (char *)(uintptr_t)buf; + iov[n++].iov_len = len; + + /* if message doesn't end with newline, one will be applied. */ + if (buf[len - 1] != '\n') { + iov[n].iov_base = &newline; + iov[n++].iov_len = 1; + } + + /* priority value between 0 ("emerg") and 7 ("debug") */ + iov[n].iov_base = pbuf; + iov[n++].iov_len = snprintf(pbuf, sizeof(pbuf), + "PRIORITY=%d\n", priority); + return writev(fd, iov, n); +} + + +/* wrapper for log stream to put messages into journal */ +static ssize_t +journal_log_write(void *c, const char *buf, size_t size) +{ + int fd = (uintptr_t)c; + + return journal_send(fd, buf, size); +} + +static int +journal_log_close(void *c) +{ + int fd = (uintptr_t)c; + + close(fd); + return 0; +} + +static cookie_io_functions_t journal_log_func = { + .write = journal_log_write, + .close = journal_log_close, +}; + +/* + * Check if stderr is going to system journal. + * This is the documented way to handle systemd journal + * + * See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ + */ +bool +log_journal_enabled(void) +{ + char *jenv, *endp = NULL; + struct stat st; + unsigned long dev, ino; + + jenv = getenv("JOURNAL_STREAM"); + if (jenv == NULL) + return false; + + if (fstat(STDERR_FILENO, &st) < 0) + return false; + + /* systemd sets colon-separated list of device and inode number */ + dev = strtoul(jenv, &endp, 10); + if (endp == NULL || *endp != ':') + return false; /* missing colon */ + + ino = strtoul(endp + 1, NULL, 10); + + return dev == st.st_dev && ino == st.st_ino; +} + +/* Connect to systemd's journal service */ +FILE * +log_journal_open(const char *id) +{ + char syslog_id[PATH_MAX]; + FILE *log_stream; + int len; + struct sockaddr_un sun = { + .sun_family = AF_UNIX, + .sun_path = "/run/systemd/journal/socket", + }; + int jfd = -1; + + len = snprintf(syslog_id, sizeof(syslog_id), + "SYSLOG_IDENTIFIER=%s\nSYSLOG_PID=%u", id, getpid()); + + /* Detect truncation of message and fallback to no journal */ + if (len >= (int)sizeof(syslog_id)) + return NULL; + + jfd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (jfd < 0) { + perror("socket"); + goto error; + } + + if (connect(jfd, (struct sockaddr *)&sun, sizeof(sun)) < 0) { + perror("connect"); + goto error; + } + + /* Send identifier as first message */ + if (write(jfd, syslog_id, len) != len) { + perror("write"); + goto error; + } + + /* redirect other log messages to journal */ + log_stream = fopencookie((void *)(uintptr_t)jfd, "w", journal_log_func); + if (log_stream != NULL) + return log_stream; + +error: + close(jfd); + return NULL; +} diff --git a/lib/log/log_private.h b/lib/log/log_private.h index 5da9c9b438..1b66057fd6 100644 --- a/lib/log/log_private.h +++ b/lib/log/log_private.h @@ -24,6 +24,22 @@ bool log_syslog_enabled(void); FILE *log_syslog_open(const char *id); #endif +#ifdef RTE_EXEC_ENV_LINUX +bool log_journal_enabled(void); +FILE *log_journal_open(const char *id); +#else +static inline bool +log_journal_enabled(void) +{ + return false; +} +static inline FILE * +log_journal_open(const char *id __rte_unused) +{ + return NULL; +} +#endif /* !RTE_EXEC_ENV_LINUX */ + bool log_timestamp_enabled(void); ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); diff --git a/lib/log/meson.build b/lib/log/meson.build index 4ac232786e..86e4452b19 100644 --- a/lib/log/meson.build +++ b/lib/log/meson.build @@ -11,4 +11,8 @@ if not is_windows sources += files('log_syslog.c') endif +if is_linux + sources += files('log_journal.c') +endif + headers = files('rte_log.h') diff --git a/lib/log/version.map b/lib/log/version.map index 8be6907840..800d3943bc 100644 --- a/lib/log/version.map +++ b/lib/log/version.map @@ -26,6 +26,7 @@ INTERNAL { global: eal_log_init; + eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; eal_log_save_pattern; eal_log_save_regexp; From patchwork Fri Nov 8 08:48:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148135 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D7E1F45CB1; Fri, 8 Nov 2024 09:49:30 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 97AE042F0A; Fri, 8 Nov 2024 09:49:14 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mails.dpdk.org (Postfix) with ESMTP id A4D4C42EDB for ; Fri, 8 Nov 2024 09:49:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055752; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hq8+RYrRdpb844fqUotGN8SY7/XojUowcyskysP07UU=; b=fMBEmRBlaIfbofIBRQ6qJIXDrVVJ8EAOhbVmo+kvF6l4UFt2/wX8J2IW0hp1+DPU5yu3q8 IWr6gi3NEsqIsgdu4s5j0+kQWAaXQ1wWi8cjxyFukM/aO3mOk4sWtyLEV/dI+le3LrXKzT ZZei2NNUZgepkNLwxRPXGLRuy6PdI2g= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-682-BcRJ7OfONqaatddPFXmrfg-1; Fri, 08 Nov 2024 03:49:08 -0500 X-MC-Unique: BcRJ7OfONqaatddPFXmrfg-1 X-Mimecast-MFC-AGG-ID: BcRJ7OfONqaatddPFXmrfg Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 0212E195395B; Fri, 8 Nov 2024 08:49:07 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4B2791953880; Fri, 8 Nov 2024 08:49:04 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , =?utf-8?q?Morten_Br?= =?utf-8?q?=C3=B8rup?= , Bruce Richardson , Chengwen Feng , Tyler Retzlaff , Dmitry Kozlyuk Subject: [PATCH v32 11/12] log: colorize log output Date: Fri, 8 Nov 2024 09:48:00 +0100 Message-ID: <20241108084802.2942435-12-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: rVyfcdXhTHL8TL9HLGl_5n0rhZHEmgmNnE51xvI11B4_1731055747 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger Like dmesg, colorize the log output (unless redirected to file). Timestamp is green, the subsystem is in yellow and the message is red if urgent, boldface if an error, and normal for info and debug messages. The default is to not use color since it may disturb automatic tests and other embedded usage. Note: add fileno() and isatty() to the Windows wrapper. Signed-off-by: Stephen Hemminger Acked-by: Morten Brørup Acked-by: Bruce Richardson Acked-by: Chengwen Feng --- app/test/test_eal_flags.c | 24 +++ doc/guides/prog_guide/log_lib.rst | 24 +++ doc/guides/rel_notes/release_24_11.rst | 2 + lib/eal/common/eal_common_options.c | 11 ++ lib/eal/common/eal_options.h | 2 + lib/eal/windows/include/rte_os_shim.h | 2 + lib/log/log.c | 23 ++- lib/log/log_color.c | 214 +++++++++++++++++++++++++ lib/log/log_internal.h | 5 + lib/log/log_private.h | 8 + lib/log/meson.build | 1 + lib/log/version.map | 1 + 12 files changed, 312 insertions(+), 5 deletions(-) create mode 100644 lib/log/log_color.c diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c index 1a062fe0e8..d37d6b8627 100644 --- a/app/test/test_eal_flags.c +++ b/app/test/test_eal_flags.c @@ -1067,6 +1067,18 @@ test_misc_flags(void) const char * const argv25[] = {prgname, prefix, mp_flag, "--log-timestamp=invalid" }; + /* Try running with --log-color */ + const char * const argv26[] = {prgname, prefix, mp_flag, + "--log-color" }; + + /* Try running with --log-color=never */ + const char * const argv27[] = {prgname, prefix, mp_flag, + "--log-color=never" }; + + /* Try running with --log-color=invalid */ + const char * const argv28[] = {prgname, prefix, mp_flag, + "--log-color=invalid" }; + /* run all tests also applicable to FreeBSD first */ if (launch_proc(argv0) == 0) { @@ -1186,6 +1198,18 @@ test_misc_flags(void) printf("Error - process did run ok with --log-timestamp=invalid parameter\n"); goto fail; } + if (launch_proc(argv26) != 0) { + printf("Error - process did not run ok with --log-color parameter\n"); + goto fail; + } + if (launch_proc(argv27) != 0) { + printf("Error - process did not run ok with --log-color=never parameter\n"); + goto fail; + } + if (launch_proc(argv28) == 0) { + printf("Error - process did run ok with --log-timestamp=invalid parameter\n"); + goto fail; + } rmdir(hugepath_dir3); rmdir(hugepath_dir2); diff --git a/doc/guides/prog_guide/log_lib.rst b/doc/guides/prog_guide/log_lib.rst index a2e95317f5..3e888b8965 100644 --- a/doc/guides/prog_guide/log_lib.rst +++ b/doc/guides/prog_guide/log_lib.rst @@ -59,6 +59,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 ------------------------------------------- @@ -138,3 +139,26 @@ To prefix all console messages with ISO format time the syntax is:: Timestamp option has no effect if using syslog because the ``syslog()`` service already does timestamping internally. + + +Color output +~~~~~~~~~~~~ + +The log library will highlight important messages. +This is controlled by the ``--log-color`` option. +The optional argument describes when color is enabled: + +:never: Do not enable color. This is the default behavior. + +:auto: Enable color only when printing to a terminal. + This is the same as ``--log-color`` with no argument. + +:always: Always print color. + +For example to enable color in logs if using terminal:: + + /path/to/app --log-color + +.. note:: + + Color output is never used for syslog or systemd journal logging. diff --git a/doc/guides/rel_notes/release_24_11.rst b/doc/guides/rel_notes/release_24_11.rst index 341606f541..543becba28 100644 --- a/doc/guides/rel_notes/release_24_11.rst +++ b/doc/guides/rel_notes/release_24_11.rst @@ -128,6 +128,8 @@ New Features * Log messages can be timestamped with ``--log-timestamp`` option. + * Log messages can be colorized with the ``--log-color`` option. + * **Updated Marvell cnxk mempool driver.** * Added mempool driver support for CN20K SoC. diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c index 7de6a25e62..79db9a47dd 100644 --- a/lib/eal/common/eal_common_options.c +++ b/lib/eal/common/eal_common_options.c @@ -73,6 +73,7 @@ eal_long_options[] = { {OPT_HUGE_UNLINK, 2, NULL, OPT_HUGE_UNLINK_NUM }, {OPT_IOVA_MODE, 1, NULL, OPT_IOVA_MODE_NUM }, {OPT_LCORES, 1, NULL, OPT_LCORES_NUM }, + {OPT_LOG_COLOR, 2, NULL, OPT_LOG_COLOR_NUM }, {OPT_LOG_LEVEL, 1, NULL, OPT_LOG_LEVEL_NUM }, {OPT_LOG_TIMESTAMP, 2, NULL, OPT_LOG_TIMESTAMP_NUM }, {OPT_TRACE, 1, NULL, OPT_TRACE_NUM }, @@ -1599,6 +1600,7 @@ bool eal_option_is_log(int opt) { switch (opt) { + case OPT_LOG_COLOR_NUM: case OPT_LOG_LEVEL_NUM: case OPT_LOG_TIMESTAMP_NUM: case OPT_SYSLOG_NUM: @@ -1869,6 +1871,14 @@ eal_parse_common_option(int opt, const char *optarg, } break; + case OPT_LOG_COLOR_NUM: + if (eal_log_color(optarg) < 0) { + EAL_LOG(ERR, "invalid parameters for --" + OPT_LOG_COLOR); + return -1; + } + break; + #ifndef RTE_EXEC_ENV_WINDOWS case OPT_TRACE_NUM: { if (eal_trace_args_save(optarg) < 0) { @@ -2235,6 +2245,7 @@ eal_common_usage(void) " Set specific log level\n" " --"OPT_LOG_LEVEL"=help Show log types and levels\n" " --"OPT_LOG_TIMESTAMP"[=] Timestamp log output\n" + " --"OPT_LOG_COLOR"[=] Colorize log messages\n" #ifndef RTE_EXEC_ENV_WINDOWS " --"OPT_TRACE"=\n" " Enable trace based on regular expression trace name.\n" diff --git a/lib/eal/common/eal_options.h b/lib/eal/common/eal_options.h index a1b52ae694..95fb4f6108 100644 --- a/lib/eal/common/eal_options.h +++ b/lib/eal/common/eal_options.h @@ -33,6 +33,8 @@ enum { OPT_HUGE_UNLINK_NUM, #define OPT_LCORES "lcores" OPT_LCORES_NUM, +#define OPT_LOG_COLOR "log-color" + OPT_LOG_COLOR_NUM, #define OPT_LOG_LEVEL "log-level" OPT_LOG_LEVEL_NUM, #define OPT_LOG_TIMESTAMP "log-timestamp" diff --git a/lib/eal/windows/include/rte_os_shim.h b/lib/eal/windows/include/rte_os_shim.h index 665c9ac93b..0e74eb19c7 100644 --- a/lib/eal/windows/include/rte_os_shim.h +++ b/lib/eal/windows/include/rte_os_shim.h @@ -30,6 +30,8 @@ #define write(fd, buf, n) _write(fd, buf, n) #define close(fd) _close(fd) #define unlink(path) _unlink(path) +#define fileno(f) _fileno(f) +#define isatty(fd) _isatty(fd) #define IPVERSION 4 diff --git a/lib/log/log.c b/lib/log/log.c index 0974adc81f..eb087d601e 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -517,12 +518,24 @@ eal_log_init(const char *id) logf = log_syslog_open(id); /* if either syslog or journal is used, then no special handling */ - if (logf) + if (logf) { rte_openlog_stream(logf); - else if (log_timestamp_enabled()) - rte_logs.print_func = log_print_with_timestamp; - else - rte_logs.print_func = vfprintf; + } else { + bool is_terminal = isatty(fileno(stderr)); + bool use_color = log_color_enabled(is_terminal); + + if (log_timestamp_enabled()) { + if (use_color) + rte_logs.print_func = color_print_with_timestamp; + else + rte_logs.print_func = log_print_with_timestamp; + } else { + if (use_color) + rte_logs.print_func = color_print; + else + rte_logs.print_func = vfprintf; + } + } } #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG diff --git a/lib/log/log_color.c b/lib/log/log_color.c new file mode 100644 index 0000000000..04eb5aa485 --- /dev/null +++ b/lib/log/log_color.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef RTE_EXEC_ENV_WINDOWS +#include +#endif + +#include "log_internal.h" +#include "log_private.h" + +enum { + LOG_COLOR_AUTO = 0, + LOG_COLOR_NEVER, + LOG_COLOR_ALWAYS, +} log_color_mode = LOG_COLOR_NEVER; + +enum color { + COLOR_NONE, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW, + COLOR_BLUE, + COLOR_MAGENTA, + COLOR_CYAN, + COLOR_WHITE, + COLOR_BOLD, + COLOR_CLEAR, +}; + +enum log_field { + LOG_FIELD_SUBSYS, + LOG_FIELD_TIME, + LOG_FIELD_ALERT, + LOG_FIELD_ERROR, + LOG_FIELD_INFO, +}; + +static const enum color field_colors[] = { + [LOG_FIELD_SUBSYS] = COLOR_YELLOW, + [LOG_FIELD_TIME] = COLOR_GREEN, + [LOG_FIELD_ALERT] = COLOR_RED, + [LOG_FIELD_ERROR] = COLOR_BOLD, + [LOG_FIELD_INFO] = COLOR_NONE, +}; + +/* If set all colors are bolder */ +static bool dark_mode; + +/* Standard terminal escape codes for colors and bold */ +static const uint8_t color_esc_code[] = { + [COLOR_RED] = 31, + [COLOR_GREEN] = 32, + [COLOR_YELLOW] = 33, + [COLOR_BLUE] = 34, + [COLOR_MAGENTA] = 35, + [COLOR_CYAN] = 36, + [COLOR_WHITE] = 37, + [COLOR_BOLD] = 1, +}; + +__rte_format_printf(4, 5) +static int +color_snprintf(char *buf, size_t len, enum log_field field, + const char *fmt, ...) +{ + enum color color = field_colors[field]; + uint8_t esc = color_esc_code[color]; + va_list args; + int ret = 0; + + va_start(args, fmt); + if (esc == 0) { + ret = vsnprintf(buf, len, fmt, args); + } else { + ret = snprintf(buf, len, + dark_mode ? "\033[1;%um" : "\033[%um", esc); + ret += vsnprintf(buf + ret, len - ret, fmt, args); + ret += snprintf(buf + ret, len - ret, "%s", "\033[0m"); + } + va_end(args); + + return ret; +} + +/* + * Controls whether color is enabled: + * modes are: + * always - enable color output regardless + * auto - enable if stderr is a terminal + * never - color output is disabled. + */ +int +eal_log_color(const char *mode) +{ + if (mode == NULL || strcmp(mode, "always") == 0) + log_color_mode = LOG_COLOR_ALWAYS; + else if (strcmp(mode, "never") == 0) + log_color_mode = LOG_COLOR_NEVER; + else if (strcmp(mode, "auto") == 0) + log_color_mode = LOG_COLOR_AUTO; + else + return -1; + + return 0; +} + +bool +log_color_enabled(bool is_terminal) +{ + char *env, *sep; + + /* Set dark mode using the defacto heuristics used by other programs */ + env = getenv("COLORFGBG"); + if (env) { + sep = strrchr(env, ';'); + if (sep && + ((sep[1] >= '0' && sep[1] <= '6') || sep[1] == '8') && + sep[2] == '\0') + dark_mode = true; + } + + if (log_color_mode == LOG_COLOR_ALWAYS) + return true; + else if (log_color_mode == LOG_COLOR_AUTO) + return is_terminal; + else + return false; +} + +/* Look ast the current message level to determine color of field */ +static enum log_field +color_msg_field(void) +{ + const int level = rte_log_cur_msg_loglevel(); + + if (level <= 0 || level >= (int)RTE_LOG_INFO) + return LOG_FIELD_INFO; + else if (level >= (int)RTE_LOG_ERR) + return LOG_FIELD_ERROR; + else + return LOG_FIELD_ALERT; +} + +__rte_format_printf(3, 0) +static int +color_fmt_msg(char *out, size_t len, const char *format, va_list ap) +{ + enum log_field field = color_msg_field(); + char buf[LINE_MAX]; + int ret = 0; + + /* format raw message */ + vsnprintf(buf, sizeof(buf), format, ap); + const char *msg = buf; + + /* + * use convention that first part of message (up to the ':' character) + * is the subsystem id and should be highlighted. + */ + const char *cp = strchr(msg, ':'); + if (cp) { + /* print first part in yellow */ + ret = color_snprintf(out, len, LOG_FIELD_SUBSYS, + "%.*s", (int)(cp - msg + 1), msg); + /* skip the first part */ + msg = cp + 1; + } + + ret += color_snprintf(out + ret, len - ret, field, "%s", msg); + return ret; +} + +__rte_format_printf(2, 0) +int +color_print(FILE *f, const char *format, va_list ap) +{ + char out[LINE_MAX]; + + /* format raw message */ + int ret = color_fmt_msg(out, sizeof(out), format, ap); + if (fputs(out, f) < 0) + return -1; + + return ret; +} + +__rte_format_printf(2, 0) +int +color_print_with_timestamp(FILE *f, const char *format, va_list ap) +{ + char out[LINE_MAX]; + char tsbuf[128]; + int ret = 0; + + if (log_timestamp(tsbuf, sizeof(tsbuf)) > 0) + ret = color_snprintf(out, sizeof(out), + LOG_FIELD_TIME, "[%s] ", tsbuf); + + ret += color_fmt_msg(out + ret, sizeof(out) - ret, format, ap); + if (fputs(out, f) < 0) + return -1; + + return ret; +} diff --git a/lib/log/log_internal.h b/lib/log/log_internal.h index 82fdc21ac2..bba7041ea3 100644 --- a/lib/log/log_internal.h +++ b/lib/log/log_internal.h @@ -50,5 +50,10 @@ void rte_eal_log_cleanup(void); __rte_internal int eal_log_timestamp(const char *fmt); +/* + * Enable or disable color in log messages + */ +__rte_internal +int eal_log_color(const char *mode); #endif /* LOG_INTERNAL_H */ diff --git a/lib/log/log_private.h b/lib/log/log_private.h index 1b66057fd6..f275346c7b 100644 --- a/lib/log/log_private.h +++ b/lib/log/log_private.h @@ -46,4 +46,12 @@ ssize_t log_timestamp(char *tsbuf, size_t tsbuflen); __rte_format_printf(2, 0) int log_print_with_timestamp(FILE *f, const char *format, va_list ap); +bool log_color_enabled(bool is_tty); + +__rte_format_printf(2, 0) +int color_print(FILE *f, const char *format, va_list ap); + +__rte_format_printf(2, 0) +int color_print_with_timestamp(FILE *f, const char *format, va_list ap); + #endif /* LOG_PRIVATE_H */ diff --git a/lib/log/meson.build b/lib/log/meson.build index 86e4452b19..b3de57b9c7 100644 --- a/lib/log/meson.build +++ b/lib/log/meson.build @@ -4,6 +4,7 @@ includes += global_inc sources = files( 'log.c', + 'log_color.c', 'log_timestamp.c', ) diff --git a/lib/log/version.map b/lib/log/version.map index 800d3943bc..09d8a4289b 100644 --- a/lib/log/version.map +++ b/lib/log/version.map @@ -25,6 +25,7 @@ DPDK_25 { INTERNAL { global: + eal_log_color; eal_log_init; eal_log_journal; # WINDOWS_NO_EXPORT eal_log_level2str; From patchwork Fri Nov 8 08:48:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Marchand X-Patchwork-Id: 148136 X-Patchwork-Delegate: david.marchand@redhat.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 09C2845CB1; Fri, 8 Nov 2024 09:49:38 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D2167432EE; Fri, 8 Nov 2024 09:49:19 +0100 (CET) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mails.dpdk.org (Postfix) with ESMTP id 0997242EDB for ; Fri, 8 Nov 2024 09:49:18 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1731055758; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tPXAGO37LkEyn725hjgaz+nt2iThQrMVhgtG4IFV5oQ=; b=CDXaGQ2FxeJmYqJDj86pXOvDUPefNTk2317oVGco1FHLvVqiRM5hq5NWBlEvYs2mg/UnAY uVFFaQLXkhL4JrbWfxjxz/EX+bVTFK+n0LbAEBRLIcGEvfVnE/0mG592+88WxEWcTyvKLL zJUMcbTsOkOOAno69q5g2+Y7oiU2xVQ= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-567-12LB5T0uO4ekxShpHAZqUg-1; Fri, 08 Nov 2024 03:49:14 -0500 X-MC-Unique: 12LB5T0uO4ekxShpHAZqUg-1 X-Mimecast-MFC-AGG-ID: 12LB5T0uO4ekxShpHAZqUg Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 7227C1936173; Fri, 8 Nov 2024 08:49:12 +0000 (UTC) Received: from dmarchan.redhat.com (unknown [10.45.224.57]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id D91DE300019E; Fri, 8 Nov 2024 08:49:09 +0000 (UTC) From: David Marchand To: dev@dpdk.org Cc: Stephen Hemminger , Tyler Retzlaff , =?utf-8?q?Morten_Br=C3=B8rup?= , Chengwen Feng , Bruce Richardson , Thomas Monjalon Subject: [PATCH v32 12/12] maintainers: update for log library Date: Fri, 8 Nov 2024 09:48:01 +0100 Message-ID: <20241108084802.2942435-13-david.marchand@redhat.com> In-Reply-To: <20241108084802.2942435-1-david.marchand@redhat.com> References: <20200814173441.23086-1-stephen@networkplumber.org> <20241108084802.2942435-1-david.marchand@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: jiZgrTtWQrrg6NxmkVbzBwqdzRaZksunOBnrmq7MqzI_1731055752 X-Mimecast-Originator: redhat.com X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org From: Stephen Hemminger "You touch it you own it". Add myself as maintainer for log library. Signed-off-by: Stephen Hemminger Acked-by: Tyler Retzlaff Acked-by: Morten Brørup Acked-by: Chengwen Feng Acked-by: Bruce Richardson --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 0eacf60b5a..0697924ff0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -193,6 +193,7 @@ F: app/test/test_threads.c F: app/test/test_version.c Logging +M: Stephen Hemminger F: lib/log/ F: doc/guides/prog_guide/log_lib.rst F: app/test/test_logs.c