chiark / gitweb /
journalctl: rework JSON output mode
authorLennart Poettering <lennart@poettering.net>
Wed, 5 Sep 2012 22:25:32 +0000 (15:25 -0700)
committerLennart Poettering <lennart@poettering.net>
Wed, 5 Sep 2012 22:25:32 +0000 (15:25 -0700)
This splits the JSON output mode into different modes: json and
json-pretty. The former printing one entry per line, the latter showing
JSON objects nicely indented and in multiple lines to make it easier to
read for humans.

TODO
man/journalctl.xml
src/journal/journal-send.c
src/journal/journalctl.c
src/shared/logs-show.c
src/shared/logs-show.h
src/systemctl/systemctl.c

diff --git a/TODO b/TODO
index 92d709ee4eddd93e1db33cfc52c8682d287c2162..e683eeaebf645d8141a5f7b1a64ff98e588a3840 100644 (file)
--- a/TODO
+++ b/TODO
@@ -49,6 +49,8 @@ Bugfixes:
 
 Features:
 
+* log fewer journal internal messages to the kernel kmsg
+
 * move keymaps to /usr/lib/... rather than /usr/lib/udev/...
 
 * journald: check whether it is OK if the client can still modify delivered journal entries
@@ -72,7 +74,7 @@ Features:
 
 * securityfs: don't mount in container
 
-* slave/shared remount root fs in container
+* slave/shared remount root fs in container might clash with CAP_SYS_MOUNTS
 
 * ability to pass fds into systemd
 
@@ -327,7 +329,7 @@ Features:
 
 * dbus: in fedora, make the machine a symlink to /etc/machine-id
 
-* dbus: on fedora, move dbus to early boot
+* dbus: move dbus to early boot
 
 * journald: reuse XZ context
 
index 1ea004fc8156b56fe101ab8ba33b484d721e7b50..b5950c94cee73d09a077766420c10e3af089af98 100644 (file)
                                 <literal>verbose</literal>,
                                 <literal>export</literal>,
                                 <literal>json</literal>,
+                                <literal>json-pretty</literal>,
                                 <literal>cat</literal>. <literal>short</literal>
                                 is the default and generates an output
                                 that is mostly identical to the
                                 Export Format</ulink> for more
                                 information). <literal>json</literal>
                                 formats entries as JSON data
-                                structures. <literal>cat</literal>
+                                structures, one per
+                                line. <literal>json-pretty</literal>
+                                also formats entries as JSON data
+                                structures, but formats them in
+                                multiple lines in order to make them
+                                more readable for
+                                humans. <literal>cat</literal>
                                 generates a very terse output only
                                 showing the actual message of each
                                 journal entry with no meta data, not
index d0f3b725ff5ee9a3a1d97e0fc5fe33f4a7fc11f8..b192f1fb888738cfaa25a80ac7ee6e14594d1324 100644 (file)
@@ -439,7 +439,7 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve
 
         memcpy(header, identifier, l);
         header[l++] = '\n';
-        header[l++] = '\n';
+        header[l++] = '\n'; /* unit id */
         header[l++] = '0' + priority;
         header[l++] = '\n';
         header[l++] = '0' + !!level_prefix;
index 6aff1f1ba3432e12909418862f23e73717092552..56a8abea57d8de67c718d162ca7374afd8b90dc8 100644 (file)
@@ -87,7 +87,7 @@ static int help(void) {
                "  -n --lines=INTEGER     Journal entries to show\n"
                "     --no-tail           Show all lines, even in follow mode\n"
                "  -o --output=STRING     Change journal output mode (short, short-monotonic,\n"
-               "                         verbose, export, json, cat)\n"
+               "                         verbose, export, json, json-pretty, cat)\n"
                "  -q --quiet             Don't show privilege warning\n"
                "  -l --local             Only local entries\n"
                "  -b --this-boot         Show data only from current boot\n"
@@ -821,11 +821,6 @@ int main(int argc, char *argv[]) {
         on_tty();
         have_pager = !arg_no_pager && !arg_follow && pager_open();
 
-        if (arg_output == OUTPUT_JSON) {
-                fputc('[', stdout);
-                fflush(stdout);
-        }
-
         for (;;) {
                 for (;;) {
                         sd_id128_t boot_id;
@@ -874,9 +869,6 @@ int main(int argc, char *argv[]) {
                 }
         }
 
-        if (arg_output == OUTPUT_JSON)
-                fputs("\n]\n", stdout);
-
 finish:
         if (j)
                 sd_journal_close(j);
index 67b20563dffae74ce1b0cb74d09853426508a80e..d60e5e53081c3cdacf828dc6562ef8837f2a9390 100644 (file)
@@ -76,7 +76,7 @@ static bool shall_print(bool show_all, char *p, size_t l) {
         return true;
 }
 
-static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
+static int output_short(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns,
                         OutputFlags flags) {
         int r;
         const void *data;
@@ -152,7 +152,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
         if (priority_len == 1 && *priority >= '0' && *priority <= '7')
                 p = *priority - '0';
 
-        if (flags & OUTPUT_MONOTONIC_MODE) {
+        if (mode == OUTPUT_SHORT_MONOTONIC) {
                 uint64_t t;
                 sd_id128_t boot_id;
 
@@ -278,17 +278,7 @@ finish:
         return r;
 }
 
-static int output_short_realtime(sd_journal *j, unsigned line,
-                                 unsigned n_columns, OutputFlags flags) {
-        return output_short(j, line, n_columns, flags & ~OUTPUT_MONOTONIC_MODE);
-}
-
-static int output_short_monotonic(sd_journal *j, unsigned line,
-                                  unsigned n_columns, OutputFlags flags) {
-        return output_short(j, line, n_columns, flags | OUTPUT_MONOTONIC_MODE);
-}
-
-static int output_verbose(sd_journal *j, unsigned line,
+static int output_verbose(sd_journal *j, OutputMode mode, unsigned line,
                           unsigned n_columns, OutputFlags flags) {
         const void *data;
         size_t length;
@@ -340,7 +330,7 @@ static int output_verbose(sd_journal *j, unsigned line,
         return 0;
 }
 
-static int output_export(sd_journal *j, unsigned line,
+static int output_export(sd_journal *j, OutputMode mode, unsigned line,
                          unsigned n_columns, OutputFlags flags) {
         sd_id128_t boot_id;
         char sid[33];
@@ -452,7 +442,7 @@ static void json_escape(const char* p, size_t l) {
         }
 }
 
-static int output_json(sd_journal *j, unsigned line,
+static int output_json(sd_journal *j, OutputMode mode, unsigned line,
                        unsigned n_columns, OutputFlags flags) {
         uint64_t realtime, monotonic;
         char *cursor;
@@ -482,21 +472,25 @@ static int output_json(sd_journal *j, unsigned line,
                 return r;
         }
 
-        if (line == 1)
-                fputc('\n', stdout);
+        if (mode == OUTPUT_JSON_PRETTY)
+                printf("{\n"
+                       "\t\"__CURSOR\" : \"%s\",\n"
+                       "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
+                       "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
+                       "\t\"_BOOT_ID\" : \"%s\"",
+                       cursor,
+                       (unsigned long long) realtime,
+                       (unsigned long long) monotonic,
+                       sd_id128_to_string(boot_id, sid));
         else
-                fputs(",\n", stdout);
-
-        printf("{\n"
-               "\t\"__CURSOR\" : \"%s\",\n"
-               "\t\"__REALTIME_TIMESTAMP\" : \"%llu\",\n"
-               "\t\"__MONOTONIC_TIMESTAMP\" : \"%llu\",\n"
-               "\t\"_BOOT_ID\" : \"%s\"",
-               cursor,
-               (unsigned long long) realtime,
-               (unsigned long long) monotonic,
-               sd_id128_to_string(boot_id, sid));
-
+                printf("{ \"__CURSOR\" : \"%s\", "
+                       "\"__REALTIME_TIMESTAMP\" : \"%llu\", "
+                       "\"__MONOTONIC_TIMESTAMP\" : \"%llu\", "
+                       "\"_BOOT_ID\" : \"%s\"",
+                       cursor,
+                       (unsigned long long) realtime,
+                       (unsigned long long) monotonic,
+                       sd_id128_to_string(boot_id, sid));
         free(cursor);
 
         SD_JOURNAL_FOREACH_DATA(j, data, length) {
@@ -514,18 +508,25 @@ static int output_json(sd_journal *j, unsigned line,
                         return -EINVAL;
                 }
 
-                fputs(",\n\t", stdout);
+                if (mode == OUTPUT_JSON_PRETTY)
+                        fputs(",\n\t", stdout);
+                else
+                        fputs(", ", stdout);
+
                 json_escape(data, c - (const char*) data);
                 fputs(" : ", stdout);
                 json_escape(c + 1, length - (c - (const char*) data) - 1);
         }
 
-        fputs("\n}", stdout);
+        if (mode == OUTPUT_JSON_PRETTY)
+                fputs("\n}\n", stdout);
+        else
+                fputs(" }\n", stdout);
 
         return 0;
 }
 
-static int output_cat(sd_journal *j, unsigned line,
+static int output_cat(sd_journal *j, OutputMode mode, unsigned line,
                       unsigned n_columns, OutputFlags flags) {
         const void *data;
         size_t l;
@@ -547,13 +548,14 @@ static int output_cat(sd_journal *j, unsigned line,
         return 0;
 }
 
-static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line,
+static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, OutputMode mode, unsigned line,
                                              unsigned n_columns, OutputFlags flags) = {
-        [OUTPUT_SHORT] = output_short_realtime,
-        [OUTPUT_SHORT_MONOTONIC] = output_short_monotonic,
+        [OUTPUT_SHORT] = output_short,
+        [OUTPUT_SHORT_MONOTONIC] = output_short,
         [OUTPUT_VERBOSE] = output_verbose,
         [OUTPUT_EXPORT] = output_export,
         [OUTPUT_JSON] = output_json,
+        [OUTPUT_JSON_PRETTY] = output_json,
         [OUTPUT_CAT] = output_cat
 };
 
@@ -566,7 +568,7 @@ int output_journal(sd_journal *j, OutputMode mode, unsigned line,
         if (n_columns <= 0)
                 n_columns = columns();
 
-        ret = output_funcs[mode](j, line, n_columns, flags);
+        ret = output_funcs[mode](j, mode, line, n_columns, flags);
         fflush(stdout);
         return ret;
 }
@@ -736,6 +738,7 @@ static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
         [OUTPUT_VERBOSE] = "verbose",
         [OUTPUT_EXPORT] = "export",
         [OUTPUT_JSON] = "json",
+        [OUTPUT_JSON_PRETTY] = "json-pretty",
         [OUTPUT_CAT] = "cat"
 };
 
index 58ff9e5760bd8b39101f07fc2f2ca2cf8cd1db39..3e6b6e0f643edebb29fc602a7cc36050eb6b6dcf 100644 (file)
@@ -33,6 +33,7 @@ typedef enum OutputMode {
         OUTPUT_VERBOSE,
         OUTPUT_EXPORT,
         OUTPUT_JSON,
+        OUTPUT_JSON_PRETTY,
         OUTPUT_CAT,
         _OUTPUT_MODE_MAX,
         _OUTPUT_MODE_INVALID = -1
@@ -40,11 +41,10 @@ typedef enum OutputMode {
 
 typedef enum OutputFlags {
         OUTPUT_SHOW_ALL       = 1 << 0,
-        OUTPUT_MONOTONIC_MODE = 1 << 1,
-        OUTPUT_FOLLOW         = 1 << 2,
-        OUTPUT_WARN_CUTOFF    = 1 << 3,
-        OUTPUT_FULL_WIDTH     = 1 << 4,
-        OUTPUT_COLOR          = 1 << 5
+        OUTPUT_FOLLOW         = 1 << 1,
+        OUTPUT_WARN_CUTOFF    = 1 << 2,
+        OUTPUT_FULL_WIDTH     = 1 << 3,
+        OUTPUT_COLOR          = 1 << 4
 } OutputFlags;
 
 int output_journal(sd_journal *j, OutputMode mode, unsigned line,
index 24818492322fc98cecb8343345874afa7e2f74fc..871a04bc1b57d8c5b1ffcde1bf3706878137ec38 100644 (file)
@@ -3871,7 +3871,7 @@ static int systemctl_help(void) {
                "  -n --lines=INTEGER  Journal entries to show\n"
                "     --follow         Follow journal\n"
                "  -o --output=STRING  Change journal output mode (short, short-monotonic,\n"
-               "                      verbose, export, json, cat)\n\n"
+               "                      verbose, export, json, json-pretty, cat)\n\n"
                "Unit Commands:\n"
                "  list-units                      List loaded units\n"
                "  start [NAME...]                 Start (activate) one or more units\n"