]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journalctl: add new output mode "short-full" (#3880)
authorLennart Poettering <lennart@poettering.net>
Wed, 3 Aug 2016 23:45:07 +0000 (01:45 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 3 Aug 2016 23:45:07 +0000 (19:45 -0400)
This new output mode formats all timestamps using the usual format_timestamp()
call we use pretty much everywhere else. Timestamps formatted this way are some
ways more useful than traditional syslog timestamps as they include weekday,
month and timezone information, while not being much longer. They are also not
locale-dependent. The primary advantage however is that they may be passed
directly to journalctl's --since= and --until= switches as soon as #3869 is
merged.

While we are at it, let's also add "short-unix" to shell completion.

man/journalctl.xml
shell-completion/bash/journalctl
shell-completion/bash/systemctl.in
shell-completion/zsh/_sd_outputmodes
src/shared/logs-show.c
src/shared/output-mode.c
src/shared/output-mode.h

index e77621d7b323a7b7ff4cf19e4faf3bffb78f4caf..c448a29a514b2d828d7a29e39c1c3d332afa390e 100644 (file)
               </listitem>
             </varlistentry>
 
+            <varlistentry>
+              <term>
+                <option>short-full</option>
+              </term>
+              <listitem>
+                <para>is very similar, but shows timestamps in the format the <option>--since=</option> and
+                <option>--until=</option> options accept. Unlike the timestamp information shown in
+                <option>short</option> output mode this mode includes weekday, year and timezone information in the
+                output, and is locale-independent.</para>
+              </listitem>
+            </varlistentry>
+
             <varlistentry>
               <term>
                 <option>short-iso</option>
         <term><option>-U</option></term>
         <term><option>--until=</option></term>
 
-        <listitem><para>Start showing entries on or newer than the
-        specified date, or on or older than the specified date,
-        respectively. Date specifications should be of the format
-        <literal>2012-10-30 18:17:16</literal>.  If the time part is
-        omitted, <literal>00:00:00</literal> is assumed.  If only the
-        seconds component is omitted, <literal>:00</literal> is
-        assumed. If the date component is omitted, the current day is
-        assumed. Alternatively the strings
-        <literal>yesterday</literal>, <literal>today</literal>,
-        <literal>tomorrow</literal> are understood, which refer to
-        00:00:00 of the day before the current day, the current day,
-        or the day after the current day,
-        respectively. <literal>now</literal> refers to the current
-        time. Finally, relative times may be specified, prefixed with
-        <literal>-</literal> or <literal>+</literal>, referring to
-        times before or after the current time, respectively. For complete
-        time and date specification, see
-        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>.
+        <listitem><para>Start showing entries on or newer than the specified date, or on or older than the specified
+        date, respectively. Date specifications should be of the format <literal>2012-10-30 18:17:16</literal>.  If the
+        time part is omitted, <literal>00:00:00</literal> is assumed.  If only the seconds component is omitted,
+        <literal>:00</literal> is assumed. If the date component is omitted, the current day is assumed. Alternatively
+        the strings <literal>yesterday</literal>, <literal>today</literal>, <literal>tomorrow</literal> are understood,
+        which refer to 00:00:00 of the day before the current day, the current day, or the day after the current day,
+        respectively. <literal>now</literal> refers to the current time. Finally, relative times may be specified,
+        prefixed with <literal>-</literal> or <literal>+</literal>, referring to times before or after the current
+        time, respectively. For complete time and date specification, see
+        <citerefentry><refentrytitle>systemd.time</refentrytitle><manvolnum>7</manvolnum></citerefentry>. Note that
+        <option>--output=short-full</option> prints timestamps that follow precisely this format.
         </para>
         </listitem>
       </varlistentry>
index 53bedcd92eacbcfffcbc5faab07cd583f7f91d4c..a999a10df18a17fb0773f78b1d08a9e69b106800 100644 (file)
@@ -65,7 +65,7 @@ _journalctl() {
                                 compopt -o filenames
                         ;;
                         --output|-o)
-                                comps='short short-iso short-precise short-monotonic verbose export json json-pretty json-sse cat'
+                                comps='short short-full short-iso short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat'
                         ;;
                         --field|-F)
                                 comps=$(journalctl --fields | sort 2>/dev/null)
index 6f2b3f122c89fcb3d1d8f6b1b8d1fb0257171d60..2a45dcbba0c3ed210e2a3643bddd88069d6fe0d7 100644 (file)
@@ -145,7 +145,7 @@ _systemctl () {
                                 comps='full enable-only disable-only'
                         ;;
                         --output|-o)
-                                comps='short short-iso short-precise short-monotonic verbose export json
+                                comps='short short-full short-iso short-precise short-monotonic short-unix verbose export json
                                        json-pretty json-sse cat'
                         ;;
                         --machine|-M)
index 3836f79b73c6c9bf54d114e21993dbf69eb4fd2a..52617c6b7aaef8e83a270c19fbc5008b119caa72 100644 (file)
@@ -1,5 +1,5 @@
 #autoload
 
 local -a _output_opts
-_output_opts=(short short-iso short-precise short-monotonic verbose export json json-pretty json-sse cat)
+_output_opts=(short short-full short-iso short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
 _describe -t output 'output mode' _output_opts || compadd "$@"
index d04728f5055b186456e560c7361380fb72c908f4..f9d9c4ed62a088d8e8653cf711308d81202ea670 100644 (file)
@@ -45,6 +45,7 @@
 #include "parse-util.h"
 #include "process-util.h"
 #include "sparse-endian.h"
+#include "stdio-util.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "terminal-util.h"
@@ -206,6 +207,108 @@ static bool print_multiline(FILE *f, unsigned prefix, unsigned n_columns, Output
         return ellipsized;
 }
 
+static int output_timestamp_monotonic(FILE *f, sd_journal *j, const char *monotonic) {
+        sd_id128_t boot_id;
+        uint64_t t;
+        int r;
+
+        assert(f);
+        assert(j);
+
+        r = -ENXIO;
+        if (monotonic)
+                r = safe_atou64(monotonic, &t);
+        if (r < 0)
+                r = sd_journal_get_monotonic_usec(j, &t, &boot_id);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get monotonic timestamp: %m");
+
+        fprintf(f, "[%5llu.%06llu]",
+                (unsigned long long) (t / USEC_PER_SEC),
+                (unsigned long long) (t % USEC_PER_SEC));
+
+        return 1 + 5 + 1 + 6 + 1;
+}
+
+static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, OutputFlags flags, const char *realtime) {
+        char buf[MAX(FORMAT_TIMESTAMP_MAX, 64)];
+        struct tm *(*gettime_r)(const time_t *, struct tm *);
+        struct tm tm;
+        uint64_t x;
+        time_t t;
+        int r;
+
+        assert(f);
+        assert(j);
+
+        r = -ENXIO;
+        if (realtime)
+                r = safe_atou64(realtime, &x);
+        if (r < 0)
+                r = sd_journal_get_realtime_usec(j, &x);
+        if (r < 0)
+                return log_error_errno(r, "Failed to get realtime timestamp: %m");
+
+        if (mode == OUTPUT_SHORT_FULL) {
+                const char *k;
+
+                if (flags & OUTPUT_UTC)
+                        k = format_timestamp_utc(buf, sizeof(buf), x);
+                else
+                        k = format_timestamp(buf, sizeof(buf), x);
+                if (!k) {
+                        log_error("Failed to format timestamp.");
+                        return -EINVAL;
+                }
+
+        } else {
+                gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r;
+                t = (time_t) (x / USEC_PER_SEC);
+
+                switch (mode) {
+
+                case OUTPUT_SHORT_UNIX:
+                        xsprintf(buf, "%10llu.%06llu", (unsigned long long) t, (unsigned long long) (x % USEC_PER_SEC));
+                        break;
+
+                case OUTPUT_SHORT_ISO:
+                        if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm)) <= 0) {
+                                log_error("Failed for format ISO time");
+                                return -EINVAL;
+                        }
+                        break;
+
+                case OUTPUT_SHORT:
+                case OUTPUT_SHORT_PRECISE:
+
+                        if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm)) <= 0) {
+                                log_error("Failed to format syslog time");
+                                return -EINVAL;
+                        }
+
+                        if (mode == OUTPUT_SHORT_PRECISE) {
+                                size_t k;
+
+                                assert(sizeof(buf) > strlen(buf));
+                                k = sizeof(buf) - strlen(buf);
+
+                                r = snprintf(buf + strlen(buf), k, ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
+                                if (r <= 0 || (size_t) r >= k) { /* too long? */
+                                        log_error("Failed to format precise time");
+                                        return -EINVAL;
+                                }
+                        }
+                        break;
+
+                default:
+                        assert_not_reached("Unknown time format");
+                }
+        }
+
+        fputs(buf, f);
+        return (int) strlen(buf);
+}
+
 static int output_short(
                 FILE *f,
                 sd_journal *j,
@@ -305,78 +408,15 @@ static int output_short(
         if (priority_len == 1 && *priority >= '0' && *priority <= '7')
                 p = *priority - '0';
 
-        if (mode == OUTPUT_SHORT_MONOTONIC) {
-                uint64_t t;
-                sd_id128_t boot_id;
-
-                r = -ENOENT;
-
-                if (monotonic)
-                        r = safe_atou64(monotonic, &t);
-
-                if (r < 0)
-                        r = sd_journal_get_monotonic_usec(j, &t, &boot_id);
-
-                if (r < 0)
-                        return log_error_errno(r, "Failed to get monotonic timestamp: %m");
-
-                fprintf(f, "[%5llu.%06llu]",
-                        (unsigned long long) (t / USEC_PER_SEC),
-                        (unsigned long long) (t % USEC_PER_SEC));
-
-                n += 1 + 5 + 1 + 6 + 1;
-
-        } else {
-                char buf[64];
-                uint64_t x;
-                time_t t;
-                struct tm tm;
-                struct tm *(*gettime_r)(const time_t *, struct tm *);
-
-                r = -ENOENT;
-                gettime_r = (flags & OUTPUT_UTC) ? gmtime_r : localtime_r;
-
-                if (realtime)
-                        r = safe_atou64(realtime, &x);
-
-                if (r < 0)
-                        r = sd_journal_get_realtime_usec(j, &x);
-
-                if (r < 0)
-                        return log_error_errno(r, "Failed to get realtime timestamp: %m");
-
-                t = (time_t) (x / USEC_PER_SEC);
-
-                switch (mode) {
-
-                case OUTPUT_SHORT_UNIX:
-                        r = snprintf(buf, sizeof(buf), "%10llu.%06llu", (unsigned long long) t, (unsigned long long) (x % USEC_PER_SEC));
-                        break;
-
-                case OUTPUT_SHORT_ISO:
-                        r = strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S%z", gettime_r(&t, &tm));
-                        break;
-
-                case OUTPUT_SHORT_PRECISE:
-                        r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm));
-                        if (r > 0)
-                                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ".%06llu", (unsigned long long) (x % USEC_PER_SEC));
-                        break;
-
-                default:
-                        r = strftime(buf, sizeof(buf), "%b %d %H:%M:%S", gettime_r(&t, &tm));
-                }
-
-                if (r <= 0) {
-                        log_error("Failed to format time.");
-                        return -EINVAL;
-                }
-
-                fputs(buf, f);
-                n += strlen(buf);
-        }
+        if (mode == OUTPUT_SHORT_MONOTONIC)
+                r = output_timestamp_monotonic(f, j, monotonic);
+        else
+                r = output_timestamp_realtime(f, j, mode, flags, realtime);
+        if (r < 0)
+                return r;
+        n += r;
 
-        if (hostname && (flags & OUTPUT_NO_HOSTNAME)) {
+        if (flags & OUTPUT_NO_HOSTNAME) {
                 /* Suppress display of the hostname if this is requested. */
                 hostname = NULL;
                 hostname_len = 0;
@@ -910,6 +950,7 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
         [OUTPUT_SHORT_PRECISE] = output_short,
         [OUTPUT_SHORT_MONOTONIC] = output_short,
         [OUTPUT_SHORT_UNIX] = output_short,
+        [OUTPUT_SHORT_FULL] = output_short,
         [OUTPUT_VERBOSE] = output_verbose,
         [OUTPUT_EXPORT] = output_export,
         [OUTPUT_JSON] = output_json,
index bec53ee0ae2f729a9465f8a5498e2d86c07f467a..67d8208ad2d88bc762d4f0c754e61b70cfa15bcc 100644 (file)
@@ -22,6 +22,7 @@
 
 static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
         [OUTPUT_SHORT] = "short",
+        [OUTPUT_SHORT_FULL] = "short-full",
         [OUTPUT_SHORT_ISO] = "short-iso",
         [OUTPUT_SHORT_PRECISE] = "short-precise",
         [OUTPUT_SHORT_MONOTONIC] = "short-monotonic",
index f37189e57fff9389808391e55a93fa4305879a80..ff29dafcb57970eecb5ecd95db25348170d54312 100644 (file)
@@ -23,6 +23,7 @@
 
 typedef enum OutputMode {
         OUTPUT_SHORT,
+        OUTPUT_SHORT_FULL,
         OUTPUT_SHORT_ISO,
         OUTPUT_SHORT_PRECISE,
         OUTPUT_SHORT_MONOTONIC,