]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journalctl: optionally, show a different field than MESSAGE in -o cat mode
authorLennart Poettering <lennart@poettering.net>
Thu, 30 Apr 2020 12:52:25 +0000 (14:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 5 May 2020 07:22:26 +0000 (09:22 +0200)
Fixes: #15621
src/shared/logs-show.c

index 6f8de0278146d9164753894b9fee22c7c58ec4ca..6737cda1d278e0228237eeed4dd98715cd14d614 100644 (file)
@@ -1016,57 +1016,83 @@ finish:
         return r;
 }
 
-static int output_cat(
+static int output_cat_field(
                 FILE *f,
                 sd_journal *j,
-                OutputMode mode,
-                unsigned n_columns,
                 OutputFlags flags,
-                Set *output_fields,
+                const char *field,
                 const size_t highlight[2]) {
 
+        const char *highlight_on, *highlight_off;
         const void *data;
-        size_t l;
+        size_t l, fl;
         int r;
-        const char *highlight_on = "", *highlight_off = "";
 
-        assert(j);
-        assert(f);
-
-        if (flags & OUTPUT_COLOR) {
+        if (FLAGS_SET(flags, OUTPUT_COLOR)) {
                 highlight_on = ANSI_HIGHLIGHT_RED;
                 highlight_off = ANSI_NORMAL;
-        }
-
-        sd_journal_set_data_threshold(j, 0);
+        } else
+                highlight_on = highlight_off = "";
 
-        r = sd_journal_get_data(j, "MESSAGE", &data, &l);
+        r = sd_journal_get_data(j, field, &data, &l);
         if (r == -EBADMSG) {
                 log_debug_errno(r, "Skipping message we can't read: %m");
                 return 0;
         }
-        if (r < 0) {
-                /* An entry without MESSAGE=? */
-                if (r == -ENOENT)
-                        return 0;
-
+        if (r == -ENOENT) /* An entry without the requested field */
+                return 0;
+        if (r < 0)
                 return log_error_errno(r, "Failed to get data: %m");
-        }
 
-        assert(l >= 8);
+        fl = strlen(field);
+        assert(l >= fl + 1);
+        assert(((char*) data)[fl] == '=');
+
+        data = (const uint8_t*) data + fl + 1;
+        l -= fl + 1;
 
-        if (highlight && (flags & OUTPUT_COLOR)) {
+        if (highlight && FLAGS_SET(flags, OUTPUT_COLOR)) {
                 assert(highlight[0] <= highlight[1]);
-                assert(highlight[1] <= l - 8);
+                assert(highlight[1] <= l);
 
-                fwrite((const char*) data + 8, 1, highlight[0], f);
+                fwrite((const char*) data, 1, highlight[0], f);
                 fwrite(highlight_on, 1, strlen(highlight_on), f);
-                fwrite((const char*) data + 8 + highlight[0], 1, highlight[1] - highlight[0], f);
+                fwrite((const char*) data + highlight[0], 1, highlight[1] - highlight[0], f);
                 fwrite(highlight_off, 1, strlen(highlight_off), f);
-                fwrite((const char*) data + 8 + highlight[1], 1, l - 8 - highlight[1], f);
+                fwrite((const char*) data + highlight[1], 1, l - highlight[1], f);
         } else
-                fwrite((const char*) data + 8, 1, l - 8, f);
+                fwrite((const char*) data, 1, l, f);
+
         fputc('\n', f);
+        return 0;
+}
+
+static int output_cat(
+                FILE *f,
+                sd_journal *j,
+                OutputMode mode,
+                unsigned n_columns,
+                OutputFlags flags,
+                Set *output_fields,
+                const size_t highlight[2]) {
+
+        const char *field;
+        Iterator iterator;
+        int r;
+
+        assert(j);
+        assert(f);
+
+        (void) sd_journal_set_data_threshold(j, 0);
+
+        if (set_isempty(output_fields))
+                return output_cat_field(f, j, flags, "MESSAGE", highlight);
+
+        SET_FOREACH(field, output_fields, iterator) {
+                r = output_cat_field(f, j, flags, field, streq(field, "MESSAGE") ? highlight : NULL);
+                if (r < 0)
+                        return r;
+        }
 
         return 0;
 }