]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
time-util: introduce TIMESTAMP_UNIX
authorFrantisek Sumsal <frantisek@sumsal.cz>
Mon, 21 Feb 2022 12:08:20 +0000 (13:08 +0100)
committerFrantisek Sumsal <frantisek@sumsal.cz>
Mon, 21 Feb 2022 12:21:58 +0000 (13:21 +0100)
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
```

src/basic/time-util.c
src/basic/time-util.h
src/test/test-time-util.c

index b659d6905d9c616dc3b8d10cd3c02d6033ed8573..c0841af8f3dbcfd3566baa58953292ab2a704871 100644 (file)
@@ -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 */
index 895af8829984437070cdb18e108fa1a164ac9a69..01a72026e395cdf60d950c700ed4d4d5e635207c 100644 (file)
@@ -34,6 +34,7 @@ typedef enum TimestampStyle {
         TIMESTAMP_US,
         TIMESTAMP_UTC,
         TIMESTAMP_US_UTC,
+        TIMESTAMP_UNIX,
         _TIMESTAMP_STYLE_MAX,
         _TIMESTAMP_STYLE_INVALID = -EINVAL,
 } TimestampStyle;
index 554693834bf92dec7d909bd609d473e228b3a5d0..799d271a443c8ae13074f571befbacefa4d7181d 100644 (file)
@@ -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);