From patchwork Wed May 24 18:36:50 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Henry Chang X-Patchwork-Id: 766618 X-Patchwork-Delegate: blogic@openwrt.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wY1Nh3tJCz9s7p for ; Thu, 25 May 2017 04:37:56 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="Ag1h+D/O"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="pLzKRS+M"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Subject:Message-Id: Date:To:From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=LOCBJG74AEVlLWVTPJZcLVldwu0vdzsPMC5SZ5QlZjE=; b=Ag1h+D/OjN0Eyh iSaIOBvhnxVM8DdLZVoHVf750noRCwHenHBxOz6qNjZSNDTznjigdpvtUL/q57HEJv+DvuHeRUzx7 dLQYblOBzm0TcV833GNbZeAgi/Wbs9WxXyijM3xwhHKXsWU/G37MV/UR7ur7WRVbY/uDeE7tPMNJ8 6JR/bifg37vECNvBvYYOgwFE3tDbMON2VBroAy7ljgGgDH6VUxbZyek6VPgtgiT7KkDww3wF/+LU0 DCfPHh/mDJrAHqx9C4JII/5oxdi4GUZD12eYLxT1WE3uACxdLO5wpKbo5YKUYOIAwZRD5Y++SeFLU KQvNoyt2Xu/KucLcPpzQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dDbA2-0008Lc-3t; Wed, 24 May 2017 18:37:30 +0000 Received: from mail-pf0-x233.google.com ([2607:f8b0:400e:c00::233]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dDb9y-0008JX-Om for lede-dev@lists.infradead.org; Wed, 24 May 2017 18:37:28 +0000 Received: by mail-pf0-x233.google.com with SMTP id 9so143505877pfj.1 for ; Wed, 24 May 2017 11:37:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=7Qqt1sSpTQD8qlIu4h//z+uhwX26gDEXNhhkmbgPbZY=; b=pLzKRS+MPO/3Qlczeuy5+c2O94EnKvM8Bz+egEYd5bjRsXen69rWr4DRYjqkCtcj/Z yJ2W6oGDZmOu/bdXU1TNXGzU4TPzz2LFDdKj8+2S4DDqDbaOB7tHUub14xjltz/e0vPn LI19cCc0/yTwy8FIX3tKEXirEhpmMLp10Sg8X00Q1BTKKnrvoIQ0Usq2eerbJTaDkkxO Z7B2PMEXTa4F9frp0rc4O3JzD2QBFq7520Qbut6zUO9z6XcsXhvHx1n+v2VjUkLgAWo5 qIN9jGly8lOBKxXE5Yex487vJVB0UArhkl55ZpJg1qUpJmtC6UdnTwYicd9xqJfN8dUA DMOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=7Qqt1sSpTQD8qlIu4h//z+uhwX26gDEXNhhkmbgPbZY=; b=Q8UnOilKQIvkGAahKcHMaOIN4LH46IVWTmOwnj1VeGVESqKvsZWk6ziQ8FNqH1Id8v gwmI3BPORLIBlGsNVM3RoBacH+dHdjVYnj6OKn8RfSmBa7hH59EpM5xuV8p5IanvJ77W UudcApu1ph7JNymlmV9ky/0Ul29M+bS25cWNNJSUCL6CQqjk1lDyrOMDCJEkBYiGI2XM cv56DBgA6WmlYwfcZ+yipxjaOG0vXPFiXtKXI+TO/4QafziX+pV0XPtTt6J7Om9rz6Xc HyonUuQB9s3lwEbQsHLo5s6EKpaz57AbtGDvEebGan+uj4NEXogtuFLLAzWf1JzXiPF+ 30hQ== X-Gm-Message-State: AODbwcCNkw4T+xbXWLAwmj3jm1Xe8uxID2nrHQ3ckXK9IQSOcjgumuge GL3b6mTOCpEpuQ== X-Received: by 10.99.1.85 with SMTP id 82mr41365012pgb.74.1495651024044; Wed, 24 May 2017 11:37:04 -0700 (PDT) Received: from localhost.localdomain (108-60-116-94.static.wiline.com. [108.60.116.94]) by smtp.gmail.com with ESMTPSA id h71sm8842394pfe.85.2017.05.24.11.37.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 24 May 2017 11:37:03 -0700 (PDT) From: Henry Chang X-Google-Original-From: Henry Chang To: lede-dev@lists.infradead.org Date: Wed, 24 May 2017 11:36:50 -0700 Message-Id: <1495651010-10151-1-git-send-email-jrhenry@flotechnologies.com> X-Mailer: git-send-email 2.7.4 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170524_113726_854892_F408B738 X-CRM114-Status: GOOD ( 16.39 ) X-Spam-Score: -2.0 (--) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-2.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [2607:f8b0:400e:c00:0:0:0:233 listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (mr.changyuheng[at]gmail.com) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Subject: [LEDE-DEV] [PATCH ubox v4] logread: Add support for output template X-BeenThere: lede-dev@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Henry Chang MIME-Version: 1.0 Sender: "Lede-dev" Errors-To: lede-dev-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Henry Chang This patch let the users be able to define the output template, which means one can decide how the output logs should look like by providing a template. With this an user can easily integrate the output logs with the existing log collecting services that only accept certain input format. It supports four pre-defined keywords: %message%, %priority%, %source%, %timestamp%. These keywords will be replaced with the corresponding information. Any other words in the template will be printed as-is. Signed-off-by: Henry Chang --- log/logread.c | 163 ++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 137 insertions(+), 26 deletions(-) diff --git a/log/logread.c b/log/logread.c index edac1d9..f06dacc 100644 --- a/log/logread.c +++ b/log/logread.c @@ -56,10 +56,25 @@ static const struct blobmsg_policy log_policy[] = { [LOG_TIME] = { .name = "time", .type = BLOBMSG_TYPE_INT64 }, }; +enum { + TPL_FIELD_MESSAGE, + TPL_FIELD_PRIORITY, + TPL_FIELD_SOURCE, + TPL_FIELD_TIMESTAMP, +}; + +static const char *TPL_FIELDS[] = { + [TPL_FIELD_MESSAGE] = "%message%", + [TPL_FIELD_PRIORITY] = "%priority%", + [TPL_FIELD_SOURCE] = "%source%", + [TPL_FIELD_TIMESTAMP] = "%timestamp%", +}; + static struct uloop_timeout retry; static struct uloop_fd sender; static regex_t regexp_preg; static const char *log_file, *log_ip, *log_port, *log_prefix, *pid_file, *hostname, *regexp_pattern; +static const char *log_template; static int log_type = LOG_STDOUT; static int log_size, log_udp, log_follow, log_trailer_null = 0; static int log_timestamp; @@ -102,6 +117,7 @@ static int log_notify(struct blob_attr *msg) struct stat s; char buf[512]; char buf_ts[32]; + char buf_p[11]; uint32_t p; char *str; time_t t; @@ -137,34 +153,118 @@ static int log_notify(struct blob_attr *msg) regexec(®exp_preg, m, 0, NULL, 0) == REG_NOMATCH) return 0; t = blobmsg_get_u64(tb[LOG_TIME]) / 1000; - if (log_timestamp) { - t_ms = blobmsg_get_u64(tb[LOG_TIME]) % 1000; - snprintf(buf_ts, sizeof(buf_ts), "[%lu.%03u] ", - (unsigned long)t, t_ms); - } + t_ms = blobmsg_get_u64(tb[LOG_TIME]) % 1000; + snprintf(buf_ts, sizeof(buf_ts), "[%lu.%03u] ", (unsigned long) t, t_ms); c = ctime(&t); p = blobmsg_get_u32(tb[LOG_PRIO]); c[strlen(c) - 1] = '\0'; str = blobmsg_format_json(msg, true); + snprintf(buf_p, sizeof buf_p, "%u", p); + + if (log_template) { + size_t len; + int tpli = -1; + + if ((len = strlen(log_template) + 1) > sizeof buf) { + fprintf(stderr, "size of template is larger than the internal buffer\n"); + return 1; + } + strncpy(buf, log_template, len); + + char *substr = buf; + for (;;) { + char *substrnext = NULL; + for (unsigned short i = 0; i < sizeof TPL_FIELDS / sizeof (char *); ++i) { + char *substrbuf = strstr(substr, TPL_FIELDS[i]); + if (!substrbuf || (substrnext && substrbuf > substrnext)) + continue; + substrnext = substrbuf; + tpli = i; + } + if (!substrnext) + break; + + substr = substrnext; + char *field = NULL; + switch (tpli) { + case TPL_FIELD_MESSAGE: + field = m; + break; + case TPL_FIELD_PRIORITY: + field = buf_p; + break; + case TPL_FIELD_SOURCE: + switch (blobmsg_get_u32(tb[LOG_SOURCE])) { + case SOURCE_KLOG: + field = "kernel"; + break; + case SOURCE_SYSLOG: + field = "syslog"; + break; + case SOURCE_INTERNAL: + field = "internal"; + break; + default: + field = "-"; + break; + } + break; + case TPL_FIELD_TIMESTAMP: + field = buf_ts; + break; + } + if (!field || tpli < 0) + continue; + + char buf2[sizeof buf] = {'\0'}; + short availen = sizeof buf2 - 1; + + availen -= substr - buf; + strncat(buf2, buf, substr - buf); + + size_t fieldlen = strlen(field); + availen -= fieldlen; + if (availen < 0) { + fprintf(stderr, "size of log is larger than the internal buffer\n"); + return 1; + } + strncat(buf2, field, fieldlen); + + size_t fieldkwlen = strlen(TPL_FIELDS[tpli]); + len = strlen(substr) - fieldkwlen; + availen -= len; + if (availen < 0) { + fprintf(stderr, "size of log is larger than the internal buffer\n"); + return 1; + } + strncat(buf2, substr + fieldkwlen, len); + + strncpy(buf, buf2, sizeof buf2 - availen); + substr += fieldlen; + } + } + if (log_type == LOG_NET) { int err; - snprintf(buf, sizeof(buf), "<%u>", p); - strncat(buf, c + 4, 16); - if (log_timestamp) { - strncat(buf, buf_ts, sizeof(buf) - strlen(buf) - 1); + if (!log_template) { + snprintf(buf, sizeof(buf), "<%u>", p); + strncat(buf, c + 4, sizeof buf_p); + if (log_timestamp) { + strncat(buf, buf_ts, sizeof(buf) - strlen(buf) - 1); + } + if (hostname) { + strncat(buf, hostname, sizeof(buf) - strlen(buf) - 1); + strncat(buf, " ", sizeof(buf) - strlen(buf) - 1); + } + if (log_prefix) { + strncat(buf, log_prefix, sizeof(buf) - strlen(buf) - 1); + strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); + } + if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG) + strncat(buf, "kernel: ", sizeof(buf) - strlen(buf) - 1); + strncat(buf, m, sizeof(buf) - strlen(buf) - 1); } - if (hostname) { - strncat(buf, hostname, sizeof(buf) - strlen(buf) - 1); - strncat(buf, " ", sizeof(buf) - strlen(buf) - 1); - } - if (log_prefix) { - strncat(buf, log_prefix, sizeof(buf) - strlen(buf) - 1); - strncat(buf, ": ", sizeof(buf) - strlen(buf) - 1); - } - if (blobmsg_get_u32(tb[LOG_SOURCE]) == SOURCE_KLOG) - strncat(buf, "kernel: ", sizeof(buf) - strlen(buf) - 1); - strncat(buf, m, sizeof(buf) - strlen(buf) - 1); if (log_udp) err = write(sender.fd, buf, strlen(buf)); else { @@ -183,11 +283,18 @@ static int log_notify(struct blob_attr *msg) uloop_timeout_set(&retry, 1000); } } else { - snprintf(buf, sizeof(buf), "%s %s%s.%s%s %s\n", - c, log_timestamp ? buf_ts : "", - getcodetext(LOG_FAC(p) << 3, facilitynames), - getcodetext(LOG_PRI(p), prioritynames), - (blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"), m); + if (!log_template) { + snprintf(buf, sizeof(buf), "%s %s%s.%s%s %s\n", + c, log_timestamp ? buf_ts : "", + getcodetext(LOG_FAC(p) << 3, facilitynames), + getcodetext(LOG_PRI(p), prioritynames), + (blobmsg_get_u32(tb[LOG_SOURCE])) ? ("") : (" kernel:"), m); + } else { + size_t buflen = strlen(buf); + buflen = (buflen < sizeof buf - 1) ? buflen : (sizeof buf - 2); + buf[buflen++] = '\n'; + buf[buflen] = '\0'; + } ret = write(sender.fd, buf, strlen(buf)); } @@ -211,6 +318,7 @@ static int usage(const char *prog) " -p PID file\n" " -h Add hostname to the message\n" " -P Prefix custom text to streamed messages\n" + " -T