From 5f59cc1593eaa251161061fe9a4ac4afb1592e6e Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Mon, 21 Feb 2022 13:08:20 +0100 Subject: [PATCH] time-util: introduce TIMESTAMP_UNIX Allow formatting timestamps as number of seconds since the Epoch for easier machine parsing. Fixes: #22567 ``` $ systemctl show systemd-journald | grep Timestamp WatchdogTimestampMonotonic=0 ExecMainStartTimestamp=Sat 2021-12-11 15:25:57 CET ExecMainStartTimestampMonotonic=13030408 ExecMainExitTimestampMonotonic=0 StateChangeTimestamp=Sat 2021-12-11 15:25:57 CET StateChangeTimestampMonotonic=13049273 InactiveExitTimestamp=Sat 2021-12-11 15:25:57 CET InactiveExitTimestampMonotonic=13030430 ActiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET ActiveEnterTimestampMonotonic=13049273 ActiveExitTimestamp=Sat 2021-12-11 15:25:57 CET ActiveExitTimestampMonotonic=12997236 InactiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET InactiveEnterTimestampMonotonic=13028890 ConditionTimestamp=Sat 2021-12-11 15:25:57 CET ConditionTimestampMonotonic=13029539 AssertTimestamp=Sat 2021-12-11 15:25:57 CET AssertTimestampMonotonic=13029540 $ systemctl show --timestamp=unix systemd-journald | grep Timestamp WatchdogTimestampMonotonic=0 ExecMainStartTimestamp=@1639232757 ExecMainStartTimestampMonotonic=13030408 ExecMainExitTimestampMonotonic=0 StateChangeTimestamp=@1639232757 StateChangeTimestampMonotonic=13049273 InactiveExitTimestamp=@1639232757 InactiveExitTimestampMonotonic=13030430 ActiveEnterTimestamp=@1639232757 ActiveEnterTimestampMonotonic=13049273 ActiveExitTimestamp=@1639232757 ActiveExitTimestampMonotonic=12997236 InactiveEnterTimestamp=@1639232757 InactiveEnterTimestampMonotonic=13028890 ConditionTimestamp=@1639232757 ConditionTimestampMonotonic=13029539 AssertTimestamp=@1639232757 AssertTimestampMonotonic=13029540 ``` (cherry picked from commit ed4a5b434517eeebc508379476cf112704e7981c) Related: #2017035 --- src/basic/time-util.c | 11 +++++++++++ src/basic/time-util.h | 1 + src/test/test-time-util.c | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index b659d6905d..c0841af8f3 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -320,11 +320,13 @@ char *format_timestamp_style( time_t sec; size_t n; bool utc = false, us = false; + int r; assert(buf); switch (style) { case TIMESTAMP_PRETTY: + case TIMESTAMP_UNIX: break; case TIMESTAMP_US: us = true; @@ -350,6 +352,14 @@ char *format_timestamp_style( if (t <= 0 || t == USEC_INFINITY) return NULL; /* Timestamp is unset */ + if (style == TIMESTAMP_UNIX) { + r = snprintf(buf, l, "@" USEC_FMT, t / USEC_PER_SEC); /* round down µs → s */ + if (r < 0 || (size_t) r >= l) + return NULL; /* Doesn't fit */ + + return buf; + } + /* Let's not format times with years > 9999 */ if (t > USEC_TIMESTAMP_FORMATTABLE_MAX) { assert(l >= STRLEN("--- XXXX-XX-XX XX:XX:XX") + 1); @@ -1632,6 +1642,7 @@ static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = { [TIMESTAMP_US] = "us", [TIMESTAMP_UTC] = "utc", [TIMESTAMP_US_UTC] = "us+utc", + [TIMESTAMP_UNIX] = "unix", }; /* Use the macro for enum → string to allow for aliases */ diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 895af88299..01a72026e3 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -34,6 +34,7 @@ typedef enum TimestampStyle { TIMESTAMP_US, TIMESTAMP_UTC, TIMESTAMP_US_UTC, + TIMESTAMP_UNIX, _TIMESTAMP_STYLE_MAX, _TIMESTAMP_STYLE_INVALID = -EINVAL, } TimestampStyle; diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c index 554693834b..799d271a44 100644 --- a/src/test/test-time-util.c +++ b/src/test/test-time-util.c @@ -325,6 +325,11 @@ TEST(format_timestamp) { assert_se(parse_timestamp(buf, &y) >= 0); assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC); + assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UNIX)); + log_debug("%s", buf); + assert_se(parse_timestamp(buf, &y) >= 0); + assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC); + assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UTC)); log_debug("%s", buf); assert_se(parse_timestamp(buf, &y) >= 0);