From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6CEA643D36; Sun, 24 Mar 2024 03:42:22 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 08B89406B8; Sun, 24 Mar 2024 03:41:34 +0100 (CET) Received: from mail-pl1-f171.google.com (mail-pl1-f171.google.com [209.85.214.171]) by mails.dpdk.org (Postfix) with ESMTP id 5A08E402EC for ; Sun, 24 Mar 2024 03:41:27 +0100 (CET) Received: by mail-pl1-f171.google.com with SMTP id d9443c01a7336-1e034607879so25623615ad.0 for ; Sat, 23 Mar 2024 19:41:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1711248086; x=1711852886; darn=dpdk.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LCYp3m42AR3Bl02fdCxypzjKxWlwIQYVWzlmXEvqwJo=; b=taSHpVp6ukoNZ58mie4uRfNcPRx2b4/Ts8/x3i5VS9xXxdztmpR3u7BTYq7RILS49M KeKv+1Dowf1ZSsjtQBHI9UkpkZZ7ewbEuWiMOcp7UsRQ4l4oAkgDUXsKDXj8/y2tq1n2 ynkCUa0HBgHgxXV3t2V3Kt9miYlZr97Mz7AjOk3Z1CIeCZoRnZhWd6Mitx6+Cd4I6ox1 dxwBxvUVlLhNmFHRHaIAP8uXuy2sl1PtBxVgZhfcTCaEw3KV61VCfUzmoS6V5+yFr7H/ +5C8k+yqlw4IvwpsoA4uBKojlLb8jzERX/cL7B9FLrdo7uQ3YhlXyfp358+jbM+qbbz+ te1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711248086; x=1711852886; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LCYp3m42AR3Bl02fdCxypzjKxWlwIQYVWzlmXEvqwJo=; b=mljAY7rwuh5WgABwt2BxboQiO+aSK9NMkA5qf+whQ0Az87SH9i7YLywsqBttjB0idz r1Ynkb0xl5wV+CfaVDA/0/AJk/Qwk+qGT0tCG5QIO600iF0NTKcY4kxP3gtjoPzdIVx9 2G6zKGvYw8DvUeFCoZk6Vtaqd2o4+jEWEnp/NCux1n2z5OvXEG7p0R6UFmnEdaC/2mTe ra3nsSQ1UWqXteU8O5nwytSH13FJiW8l6oJD9TbBoY/FJjflAKKrBMgJi2JnYqanzriM pqC0j1Vd3PiOWnR8dxh7ToofTSIWorgr3xTU5PVkpT0pC8zFCKsO6GxZcrMzPDBAaBQ4 vCtw== X-Gm-Message-State: AOJu0YywQ/Em0Is0WhgKwn/nWtmXvwn75+fZwzNPUTB/MhFHMpfsFwKt c6f1KNb89ZOUjBNtwUlHfkvh25zVshqerot6LSHFejYeoKRZf6q59e4ydLqjtuITFUcSXXr/bcS d X-Google-Smtp-Source: AGHT+IF7XgmNXk8AH99VyNhqznazLQIcdk/PHeLl9qAd7uj56dqWdFRVNuCI5Bk42WTi6n2tq/RsQw== X-Received: by 2002:a17:903:186:b0:1dd:7df8:9ed7 with SMTP id z6-20020a170903018600b001dd7df89ed7mr5526206plg.15.1711248086613; Sat, 23 Mar 2024 19:41:26 -0700 (PDT) Received: from hermes.local (204-195-123-203.wavecable.com. [204.195.123.203]) by smtp.gmail.com with ESMTPSA id q17-20020a17090311d100b001dc3c4e7a12sm2244980plh.14.2024.03.23.19.41.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 23 Mar 2024 19:41:26 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v11 8/9] log: add support for systemd journal Date: Sat, 23 Mar 2024 19:33:30 -0700 Message-ID: <20240324024109.306614-9-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240324024109.306614-1-stephen@networkplumber.org> References: <20200814173441.23086-1-stephen@networkplumber.org> <20240324024109.306614-1-stephen@networkplumber.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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 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/ The journal protocol supports more information that could be added later. Signed-off-by: Stephen Hemminger --- lib/log/log.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 136 insertions(+), 5 deletions(-) diff --git a/lib/log/log.c b/lib/log/log.c index bd488dff1b..4cfa160e3b 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -13,15 +13,20 @@ #include #include +#ifdef RTE_EXEC_ENV_WINDOWS +#include +#else +#include +#include +#include +#include +#endif + #include #include #include "log_internal.h" -#ifdef RTE_EXEC_ENV_WINDOWS -#include -#endif - struct rte_log_dynamic_type { const char *name; uint32_t loglevel; @@ -39,11 +44,13 @@ enum eal_log_time_format { typedef int (*log_print_t)(FILE *f, uint32_t level, const char *fmt, va_list ap); static int log_print(FILE *f, uint32_t level, const char *format, va_list ap); + /** The rte_log structure. */ static struct rte_logs { uint32_t type; /**< Bitfield with enabled logs. */ uint32_t level; /**< Log level. */ FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */ + int journal_fd; /**< Journal file descriptor if using */ log_print_t print_func; enum eal_log_time_format time_format; @@ -681,6 +688,116 @@ log_print_with_timestamp(FILE *f, uint32_t level, return log_print(f, level, format, ap); } +#ifdef RTE_EXEC_ENV_LINUX +/* + * send message using journal protocol to journald + */ +__rte_format_printf(3, 0) +static int +journal_print(FILE *f __rte_unused, uint32_t level, const char *format, va_list ap) +{ + struct iovec iov[3]; + char *buf = NULL; + size_t len; + char msg[] = "MESSAGE="; + char *prio; + + iov[0].iov_base = msg; + iov[0].iov_len = strlen(msg); + + len = vasprintf(&buf, format, ap); + if (len == 0) + return 0; + + /* check that message ends with newline */ + if (buf[len - 1] != '\n') { + char *clone = alloca(len + 1); + if (clone == NULL) + return 0; + memcpy(clone, buf, len); + clone[len++] = '\n'; + buf = clone; + } + + iov[1].iov_base = buf; + iov[1].iov_len = len; + + /* priority value between 0 ("emerg") and 7 ("debug") */ + len = asprintf(&prio, "PRIORITY=%i\n", level - 1); + iov[2].iov_base = prio; + iov[2].iov_len = len; + + return writev(rte_logs.journal_fd, iov, 3); +} + +static void +journal_send_id(int fd, const char *id) +{ + char *syslog_id = NULL; + size_t len; + + len = asprintf(&syslog_id, "SYSLOG_IDENTIFIER=%s\n", id); + if (len > 0) + write(fd, syslog_id, len); + +} + +/* + * Check if stderr is going to system journal. + * This is the documented way to handle systemd journal + * + * See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/ + * + */ +static bool +using_journal(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; +} + +/* + * If we are being run as systemd service and stderr is going to journal + * then upgrade to use journal protocol. + */ +static int +open_journal(void) +{ + struct sockaddr_un sun = { + .sun_family = AF_UNIX, + .sun_path = "/run/systemd/journal/socket", + }; + int s; + + s = socket(AF_UNIX, SOCK_DGRAM, 0); + if (s < 0) + return -1; + + if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) { + close(s); + return -1; + } + return s; +} +#endif + /* initialize logging */ void eal_log_init(const char *id __rte_unused) @@ -689,8 +806,22 @@ eal_log_init(const char *id __rte_unused) if (rte_logs.file != NULL) return; - if (rte_logs.time_format != EAL_LOG_TIMESTAMP_NONE) +#ifdef RTE_EXEC_ENV_LINUX + if (using_journal()) { + int jfd = open_journal(); + + if (jfd < 0) { + RTE_LOG_LINE(NOTICE, EAL, "Cannot connect to journal"); + } else { + rte_logs.journal_fd = jfd; + rte_logs.print_func = journal_print; + journal_send_id(jfd, id); + } + } else +#endif + if (rte_logs.time_format != EAL_LOG_TIMESTAMP_NONE) { rte_logs.print_func = log_print_with_timestamp; + } #if RTE_LOG_DP_LEVEL >= RTE_LOG_DEBUG RTE_LOG(NOTICE, EAL, -- 2.43.0