]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib: add RFC3164 logging timestamps
authorDavid Lamparter <equinox@diac24.net>
Thu, 8 Apr 2021 12:28:43 +0000 (14:28 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Fri, 18 Jun 2021 19:05:21 +0000 (21:05 +0200)
This is old-style syslog, used among other things for /dev/log.

Signed-off-by: David Lamparter <equinox@diac24.net>
lib/zlog.c
lib/zlog.h

index e843c1e475e2945978e24be7136d0d48aa795040..d88337cb834be3f99955b6cf8a93072e086eef41 100644 (file)
@@ -117,8 +117,14 @@ struct zlog_msg {
         * Valid if ZLOG_TS_ISO8601 is set.
         * (0 if timestamp has not been formatted yet)
         */
-       uint32_t ts_flags;
        char ts_str[32], *ts_dot, ts_zonetail[8];
+       uint32_t ts_flags;
+
+       /* "mmm dd hh:mm:ss" for 3164 legacy syslog - too dissimilar from
+        * the above, so just kept separately here.
+        */
+       uint32_t ts_3164_flags;
+       char ts_3164_str[16];
 
        /* at the time of writing, 16 args was the actual maximum of arguments
         * to a single zlog call.  Particularly printing flag bitmasks seems
@@ -746,6 +752,35 @@ size_t zlog_msg_ts(struct zlog_msg *msg, struct fbuf *out, uint32_t flags)
        }
 }
 
+size_t zlog_msg_ts_3164(struct zlog_msg *msg, struct fbuf *out, uint32_t flags)
+{
+       flags &= ZLOG_TS_UTC;
+
+       if (!msg->ts_3164_str[0] || flags != msg->ts_3164_flags) {
+               /* these are "hardcoded" in RFC3164, so they're here too... */
+               static const char *const months[12] = {
+                       "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+                       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+               };
+               struct tm tm;
+
+               /* RFC3164 explicitly asks for local time, but common usage
+                * also includes UTC.
+                */
+               if (flags & ZLOG_TS_UTC)
+                       gmtime_r(&msg->ts.tv_sec, &tm);
+               else
+                       localtime_r(&msg->ts.tv_sec, &tm);
+
+               snprintfrr(msg->ts_3164_str, sizeof(msg->ts_3164_str),
+                          "%3s %2d %02d:%02d:%02d", months[tm.tm_mon],
+                          tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+
+               msg->ts_3164_flags = flags;
+       }
+       return bputs(out, msg->ts_3164_str);
+}
+
 void zlog_set_prefix_ec(bool enable)
 {
        atomic_store_explicit(&zlog_ec, enable, memory_order_relaxed);
index 452dbcbd0f15e3dfa8507d44f2bdd2818bd7ad36..f71d28c99a46835ff794d06bd217242f6069af43 100644 (file)
@@ -168,6 +168,10 @@ extern void zlog_msg_args(struct zlog_msg *msg, size_t *hdrlen,
 extern size_t zlog_msg_ts(struct zlog_msg *msg, struct fbuf *out,
                          uint32_t flags);
 
+/* "mmm dd hh:mm:ss" for RFC3164 syslog.  Only ZLOG_TS_UTC for flags. */
+extern size_t zlog_msg_ts_3164(struct zlog_msg *msg, struct fbuf *out,
+                              uint32_t flags);
+
 /* This list & struct implements the actual logging targets.  It is accessed
  * lock-free from all threads, and thus MUST only be changed atomically, i.e.
  * RCU.