get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/138825/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 138825,
    "url": "https://patches.dpdk.org/api/patches/138825/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20240326173552.97249-15-stephen@networkplumber.org/",
    "project": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<20240326173552.97249-15-stephen@networkplumber.org>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20240326173552.97249-15-stephen@networkplumber.org",
    "date": "2024-03-26T17:34:34",
    "name": "[v14,14/15] log: add support for systemd journal",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "4512a39b94790268cb4e005357910395d1792b48",
    "submitter": {
        "id": 27,
        "url": "https://patches.dpdk.org/api/people/27/?format=api",
        "name": "Stephen Hemminger",
        "email": "stephen@networkplumber.org"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20240326173552.97249-15-stephen@networkplumber.org/mbox/",
    "series": [
        {
            "id": 31621,
            "url": "https://patches.dpdk.org/api/series/31621/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=31621",
            "date": "2024-03-26T17:34:20",
            "name": "Logging unification and improvments",
            "version": 14,
            "mbox": "https://patches.dpdk.org/series/31621/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/138825/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/138825/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "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])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 52CC843D5A;\n\tTue, 26 Mar 2024 18:37:51 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 44D2D42D27;\n\tTue, 26 Mar 2024 18:36:26 +0100 (CET)",
            "from mail-pf1-f178.google.com (mail-pf1-f178.google.com\n [209.85.210.178])\n by mails.dpdk.org (Postfix) with ESMTP id E01F541153\n for <dev@dpdk.org>; Tue, 26 Mar 2024 18:36:17 +0100 (CET)",
            "by mail-pf1-f178.google.com with SMTP id\n d2e1a72fcca58-6e88e4c8500so4120904b3a.2\n for <dev@dpdk.org>; Tue, 26 Mar 2024 10:36:17 -0700 (PDT)",
            "from hermes.local (204-195-123-203.wavecable.com. [204.195.123.203])\n by smtp.gmail.com with ESMTPSA id\n u6-20020aa78386000000b006e58da8bb6asm6205546pfm.132.2024.03.26.10.36.15\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 26 Mar 2024 10:36:16 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=networkplumber-org.20230601.gappssmtp.com; s=20230601; t=1711474577;\n x=1712079377; darn=dpdk.org;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=cm7mVE++Nm52YxNTfrtG5Pgi3cLHR6O+yO99pXua/HY=;\n b=gwNHSXqiiBiQyTfjUO41C38J9UNaTTWF+HwSCekeI6gfI15PmGRhac5d0UKJ2RbSzh\n 62HDpvYCg8yeogJ/IPkAGOLoIerf7FZfRJyr3kGfo7lQ+qNSwV7396dWu6UBxT5H33f6\n Qh254AEehihhMFsqSXrbzRtic9/mIlYZtctt0wkOcnMPsKTsFGvPh+KuiQVcQYfv7WMY\n 4GW7TXbRLgZ2x5B6jFYnAwU+obUCmobgiangUNxllONFLK6ORpVXolFgfNL8J+t5lugX\n EIVOOqnRIHwDO5gL/GBkJvXoyMdArdSb6OaXThOOkG/4/0hyoyNbZlRUri2KYNtGKWnx\n 4Jlg==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1711474577; x=1712079377;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc\n :subject:date:message-id:reply-to;\n bh=cm7mVE++Nm52YxNTfrtG5Pgi3cLHR6O+yO99pXua/HY=;\n b=Ydg52EXdEpMJ8YLT/OZ5x7nCZ2IMC19W1VO2js06Y1aLUSmpyKDDpaY7d926CiifKB\n Lc7/qpZbKyDE6fOA1PRApWLMZoYj2ju+0+mi9csSuF+xMfUuZzVXP584v0jeJ+H7qhL+\n kYXm052NFLmnZmFIHCqeuKpiGV8e2cyy2m4IX6SHfB+uYdqfCNDjTmByvpqS2FumiFfF\n 9RM66uzdqHFzSSQDO0Tng6b2PR1z+IkNugiOmcP+VjHyi79IbZXgOFfJBuC+Eat4Fir4\n Mibff7BPB+f1XDoIscY2XGxkbCk7G8W8K77h2k710Wy/8XPzWKEHFDo+QbewwxiVh8zs\n coKw==",
        "X-Gm-Message-State": "AOJu0Yw5IzrwBqc1d1gVOUmkT44I6sxSZGmVDh4EfnQ2I0iTfiouWN/h\n 9aFTr8kJiXVHt9KgADNas9ei8i8ejb3oiJhK0u369m3Qm+2ipZ9K97yORIdg0KPO7QX4EUszSh0\n D",
        "X-Google-Smtp-Source": "\n AGHT+IHdnGEY/Xy3m10N92oUjp8uZBa1J0RIMgxVOkSp7a2NLjZnCKH3Y1m8vzMyZAojFE8u64lZdg==",
        "X-Received": "by 2002:a05:6a00:1482:b0:6ea:acbe:5188 with SMTP id\n v2-20020a056a00148200b006eaacbe5188mr3643829pfu.32.1711474577013;\n Tue, 26 Mar 2024 10:36:17 -0700 (PDT)",
        "From": "Stephen Hemminger <stephen@networkplumber.org>",
        "To": "dev@dpdk.org",
        "Cc": "Stephen Hemminger <stephen@networkplumber.org>",
        "Subject": "[PATCH v14 14/15] log: add support for systemd journal",
        "Date": "Tue, 26 Mar 2024 10:34:34 -0700",
        "Message-ID": "<20240326173552.97249-15-stephen@networkplumber.org>",
        "X-Mailer": "git-send-email 2.43.0",
        "In-Reply-To": "<20240326173552.97249-1-stephen@networkplumber.org>",
        "References": "<20200814173441.23086-1-stephen@networkplumber.org>\n <20240326173552.97249-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 <dev.dpdk.org>",
        "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://mails.dpdk.org/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org"
    },
    "content": "If DPDK application is being run as a systemd service, then\nit can use the journal protocol which allows putting more information\nin the log such as priority and other information.\n\nThe use of journal protocol is automatically detected and\nhandled.  Rather than having a dependency on libsystemd,\njust use the protocol directly as defined in:\n\thttps://systemd.io/JOURNAL_NATIVE_PROTOCOL/\n\nSigned-off-by: Stephen Hemminger <stephen@networkplumber.org>\n---\n lib/log/log.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 160 insertions(+), 2 deletions(-)",
    "diff": "diff --git a/lib/log/log.c b/lib/log/log.c\nindex d8974c66db..8e2319b3f0 100644\n--- a/lib/log/log.c\n+++ b/lib/log/log.c\n@@ -17,6 +17,10 @@\n #include <rte_os_shim.h>\n #else\n #include <syslog.h>\n+#include <sys/uio.h>\n+#include <sys/stat.h>\n+#include <sys/socket.h>\n+#include <sys/un.h>\n #endif\n \n #include <rte_log.h>\n@@ -56,6 +60,7 @@ static struct rte_logs {\n \tFILE *file;     /**< Output file set by rte_openlog_stream, or NULL. */\n #ifndef RTE_EXEC_ENV_WINDOWS\n \tenum eal_log_syslog syslog_opt;\n+\tint journal_fd;\n #endif\n \tlog_print_t print_func;\n \n@@ -758,6 +763,146 @@ static cookie_io_functions_t syslog_log_func = {\n \t.write = syslog_log_write,\n \t.close = syslog_log_close,\n };\n+\n+/*\n+ * send message using journal protocol to journald\n+ */\n+static int\n+journal_send(uint32_t level, const char *buf, size_t len)\n+{\n+\tstruct iovec iov[3];\n+\tchar msg[] = \"MESSAGE=\";\n+\tchar prio[32];\n+\tint ret;\n+\n+\tiov[0].iov_base = msg;\n+\tiov[0].iov_len = strlen(msg);\n+\n+\tiov[1].iov_base = (char *)(uintptr_t)buf;\n+\tiov[1].iov_len = len;\n+\n+\t/* priority value between 0 (\"emerg\") and 7 (\"debug\") */\n+\tiov[2].iov_base = prio;\n+\tiov[2].iov_len = snprintf(prio, sizeof(prio),\n+\t\t\t\t  \"PRIORITY=%i\\n\", level - 1);\n+\n+\tret = writev(rte_logs.journal_fd, iov, 3);\n+\treturn ret;\n+}\n+\n+__rte_format_printf(3, 0)\n+static int\n+journal_print(FILE *f __rte_unused, uint32_t level, const char *format, va_list ap)\n+{\n+\tchar *buf = NULL;\n+\tint ret, len;\n+\n+\tlen = vasprintf(&buf, format, ap);\n+\tif (len == 0)\n+\t\treturn 0;\n+\n+\t/* check that message ends with newline, if not add one */\n+\tif (buf[len - 1] != '\\n') {\n+\t\tchar *clone = malloc(len + 1);\n+\t\tif (clone == NULL) {\n+\t\t\tfree(buf);\n+\t\t\treturn 0;\n+\t\t}\n+\n+\t\tmemcpy(clone, buf, len);\n+\t\tclone[len++] = '\\n';\n+\t\tfree(buf);\n+\t\tbuf = clone;\n+\t}\n+\n+\tret = journal_send(level, buf, len);\n+\tfree(buf);\n+\treturn ret;\n+}\n+\n+/* wrapper for log stream to put messages into journal */\n+static ssize_t\n+journal_log_write(__rte_unused void *c, const char *buf, size_t size)\n+{\n+\treturn journal_send(rte_log_cur_msg_loglevel(), buf, size);\n+}\n+\n+static cookie_io_functions_t journal_log_func = {\n+\t.write = journal_log_write,\n+};\n+\n+/*\n+ * Check if stderr is going to system journal.\n+ * This is the documented way to handle systemd journal\n+ *\n+ * See: https://systemd.io/JOURNAL_NATIVE_PROTOCOL/\n+ *\n+ */\n+static bool\n+using_journal(void)\n+{\n+\tchar *jenv, *endp = NULL;\n+\tstruct stat st;\n+\tunsigned long dev, ino;\n+\n+\tjenv = getenv(\"JOURNAL_STREAM\");\n+\tif (jenv == NULL)\n+\t\treturn false;\n+\n+\tif (fstat(STDERR_FILENO, &st) < 0)\n+\t\treturn false;\n+\n+\t/* systemd sets colon-separated list of device and inode number */\n+\tdev = strtoul(jenv, &endp, 10);\n+\tif (endp == NULL || *endp != ':')\n+\t\treturn false;\t/* missing colon */\n+\n+\tino = strtoul(endp + 1, NULL, 10);\n+\n+\treturn dev == st.st_dev && ino == st.st_ino;\n+}\n+\n+/* Connect to systemd's journal service */\n+static int\n+open_journal(const char *id)\n+{\n+\tchar *syslog_id = NULL;\n+\tstruct sockaddr_un sun = {\n+\t\t.sun_family = AF_UNIX,\n+\t\t.sun_path = \"/run/systemd/journal/socket\",\n+\t};\n+\tssize_t len;\n+\tint s;\n+\n+\ts = socket(AF_UNIX, SOCK_DGRAM, 0);\n+\tif (s < 0)\n+\t\treturn -1;\n+\n+\tif (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0)\n+\t\tgoto error;\n+\n+\t/* Send syslog identifier as first message */\n+\tlen = asprintf(&syslog_id, \"SYSLOG_IDENTIFIER=%s\\n\", id);\n+\tif (len == 0)\n+\t\tgoto error;\n+\n+\tif (write(s, syslog_id, len) != len)\n+\t\tgoto error;\n+\n+\tfree(syslog_id);\n+\n+\t/* redirect other log messages to journal */\n+\tFILE *log_stream = fopencookie(NULL, \"w\", journal_log_func);\n+\tif (log_stream != NULL)\n+\t\tdefault_log_stream = log_stream;\n+\n+\treturn s;\n+\n+error:\n+\tfree(syslog_id);\n+\tclose(s);\n+\treturn -1;\n+}\n #endif\n \n \n@@ -765,11 +910,24 @@ static cookie_io_functions_t syslog_log_func = {\n static void\n log_output_selection(const char *id)\n {\n+#ifdef RTE_EXEC_ENV_WINDOWS\n \tRTE_SET_USED(id);\n-\n-#ifndef RTE_EXEC_ENV_WINDOWS\n+#else\n \tbool is_terminal = isatty(STDERR_FILENO);\n \n+\t/* If stderr is redirected to systemd journal then upgrade */\n+\tif (using_journal()) {\n+\t\tint jfd = open_journal(id);\n+\n+\t\tif (jfd < 0) {\n+\t\t\tRTE_LOG_LINE(NOTICE, EAL, \"Cannot connect to journal: %s\",\n+\t\t\t\t     strerror(errno));\n+\t\t} else {\n+\t\t\trte_logs.print_func = journal_print;\n+\t\t\treturn;\n+\t\t}\n+\t}\n+\n \tif (!(rte_logs.syslog_opt == EAL_LOG_SYSLOG_NONE ||\n \t      (rte_logs.syslog_opt == EAL_LOG_SYSLOG_AUTO && is_terminal))) {\n \t\tint flags = LOG_NDELAY | LOG_PID;\n",
    "prefixes": [
        "v14",
        "14/15"
    ]
}