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 C89D243D49; Mon, 25 Mar 2024 21:55:39 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 90156410D0; Mon, 25 Mar 2024 21:54:35 +0100 (CET) Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) by mails.dpdk.org (Postfix) with ESMTP id 718E640DDE for ; Mon, 25 Mar 2024 21:54:29 +0100 (CET) Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-1e0d82c529fso5677215ad.2 for ; Mon, 25 Mar 2024 13:54:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1711400068; x=1712004868; 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=d/UE9ipVPe9mD7+Cgp8jISoE1qnPb3z27iLpF4O0SEQ=; b=3UGI00PJsmcndQHI1xYJRawSNRvOc9vgLc38sOAyCC7MV6bPm1BhtUyP4FJ2guZvbk e53i+0BSdIvPFzZcmk/y4LEgMevL6AbxzZ7khUozkpi0en4BxpJ7zB50I6qAsbAxRlO9 umptKT2OdSvnuusHCuRYlGbIcRk0en/u1mQiOoe/LnZH2WMRPAlP8CvBaFVx2+AShuMd zsxELhy7QvmrG7xJLiwM7Usf/AD/x49S0Dg3HUoWtpG79KVUycCIvO+hPexmB+SuZ9OF GeLVUJ4p+kGwIZhvs6Dk/OEBXmOuUVv1M6AjJzPXnd5KLI+v/ynZevtdg9s0vujdT5dD z2Vw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1711400068; x=1712004868; 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=d/UE9ipVPe9mD7+Cgp8jISoE1qnPb3z27iLpF4O0SEQ=; b=dUDzi54aoMKucVc0l4q664rriLc4RWi4ppAf6M252M1VA1teQJs63qwTIjAjCGuTMW 6mWJGSrooPBHGJvbLia4duSJL1RULDHNiYObUBBphlPAEF7NGbJL/Bu3Np1gylqPAz0Y NvkPRUFYyifDPU97QaA6uR9g8q3yvacdJ7EJ8cpfze3RFIkGA+UfDFO1GpR6yGMaW85l nvmXKmLDbC2bAKdRUW7YHJZaVCreAyuOnLTPbq4IJKhmQJfuSMz7UGYWv6Q7YnfxkfRv IaCssO6wR78chAIqU9DS2ADCMHyOoVTdbHr545OYFehThYYglbUMDclOXUpQE+XZp6EL Q90A== X-Gm-Message-State: AOJu0YwVVq4KuKJCIRuKptm7GV2T7WIMjs8aP6f8MB+DgiJOR33v6O76 Kgt0UTe07TzlnP7FrgnsrMr2uLmT4QCTvyp5AOiff/7s2rKU0ZIIYy0P++wYTsKo5ZPQGlMGwYp w X-Google-Smtp-Source: AGHT+IHphrNR34HwvHP4H5FbYwTt4xi23qv1e20oBqRi7iho0zwL6TYhZP2M3On29ml7TgUaWxmP1A== X-Received: by 2002:a17:902:e80d:b0:1e0:afa0:d515 with SMTP id u13-20020a170902e80d00b001e0afa0d515mr5797214plg.29.1711400068632; Mon, 25 Mar 2024 13:54:28 -0700 (PDT) Received: from hermes.local (204-195-123-203.wavecable.com. [204.195.123.203]) by smtp.gmail.com with ESMTPSA id b18-20020a170903229200b001e0b5eee802sm3164487plh.123.2024.03.25.13.54.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Mar 2024 13:54:28 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Cc: Stephen Hemminger Subject: [PATCH v12 12/14] log: add support for systemd journal Date: Mon, 25 Mar 2024 13:47:09 -0700 Message-ID: <20240325205405.669897-13-stephen@networkplumber.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240325205405.669897-1-stephen@networkplumber.org> References: <20200814173441.23086-1-stephen@networkplumber.org> <20240325205405.669897-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/ Signed-off-by: Stephen Hemminger --- lib/log/log.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 2 deletions(-) diff --git a/lib/log/log.c b/lib/log/log.c index d8974c66db..0f7bdb3f25 100644 --- a/lib/log/log.c +++ b/lib/log/log.c @@ -17,6 +17,10 @@ #include #else #include +#include +#include +#include +#include #endif #include @@ -56,6 +60,7 @@ static struct rte_logs { FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */ #ifndef RTE_EXEC_ENV_WINDOWS enum eal_log_syslog syslog_opt; + int journal_fd; #endif log_print_t print_func; @@ -758,6 +763,112 @@ static cookie_io_functions_t syslog_log_func = { .write = syslog_log_write, .close = syslog_log_close, }; + + +/* + * 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 not add one */ + 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); +} + +/* + * 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; +} + +/* Connect to systemd's journal service */ +static int +open_journal(const char *id) +{ + char *syslog_id = NULL; + struct sockaddr_un sun = { + .sun_family = AF_UNIX, + .sun_path = "/run/systemd/journal/socket", + }; + ssize_t len; + int s; + + s = socket(AF_UNIX, SOCK_DGRAM, 0); + if (s < 0) + return -1; + + if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) + goto error; + + /* Send syslog identifier as first message */ + len = asprintf(&syslog_id, "SYSLOG_IDENTIFIER=%s\n", id); + if (len == 0) + goto error; + + if (write(s, syslog_id, len) != len) + goto error; + + return s; +error: + close(s); + return -1; +} #endif @@ -765,11 +876,24 @@ static cookie_io_functions_t syslog_log_func = { static void log_output_selection(const char *id) { +#ifdef RTE_EXEC_ENV_WINDOWS RTE_SET_USED(id); - -#ifndef RTE_EXEC_ENV_WINDOWS +#else bool is_terminal = isatty(STDERR_FILENO); + /* If stderr is redirected to systemd journal then upgrade */ + if (using_journal()) { + int jfd = open_journal(id); + + if (jfd < 0) { + RTE_LOG_LINE(NOTICE, EAL, "Cannot connect to journal: %s", + strerror(errno)); + } else { + rte_logs.print_func = journal_print; + return; + } + } + if (!(rte_logs.syslog_opt == EAL_LOG_SYSLOG_NONE || (rte_logs.syslog_opt == EAL_LOG_SYSLOG_AUTO && is_terminal))) { int flags = LOG_NDELAY | LOG_PID; -- 2.43.0