summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2020-04-30 14:52:25 +0200
committerLennart Poettering <lennart@poettering.net>2020-05-05 09:22:26 +0200
commit4d5d1bba731f7dabc4511abce305584d769dfe60 (patch)
treed8731ce5322ce2bbd9910d200fb11611e7e73c28
parent54ff74d2731bebbdc96e12d4a631068c5060c62f (diff)
downloadsystemd-4d5d1bba731f7dabc4511abce305584d769dfe60.tar.gz
journalctl: optionally, show a different field than MESSAGE in -o cat mode
Fixes: #15621
-rw-r--r--src/shared/logs-show.c80
1 files changed, 53 insertions, 27 deletions
diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c
index 6f8de02781..6737cda1d2 100644
--- a/src/shared/logs-show.c
+++ b/src/shared/logs-show.c
@@ -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;
}