journalctl: add with-unit mode

When dealing with a large number of template instances, for example
when launching daemons per VRF, it is hard for operators to correlate
log lines to arguments.
Add a new with-unit mode which, if available, prefixes unit and user
unit names when displaying its log messages instead of the syslog
identifier. It will also use the full timestamp with timezones, like
the short-full mode.
This commit is contained in:
Luca Boccassi 2018-05-22 12:22:00 +01:00 committed by Zbigniew Jędrzejewski-Szmek
parent c1a1b409ce
commit 49805b3d81
7 changed files with 38 additions and 9 deletions

View File

@ -369,6 +369,18 @@
not even a timestamp.</para>
</listitem>
</varlistentry>
<varlistentry>
<term>
<option>with-unit</option>
</term>
<listitem>
<para>similar to short-full, but prefixes the unit and
user unit names instead of the traditional syslog
identifier. Useful when using templated instances, as it
will include the arguments in the unit names.</para>
</listitem>
</varlistentry>
</variablelist>
</listitem>
</varlistentry>

View File

@ -66,7 +66,7 @@ _journalctl() {
compopt -o filenames
;;
--output|-o)
comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat'
comps='short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat with-unit'
;;
--field|-F)
comps=$(journalctl --fields | sort 2>/dev/null)

View File

@ -2,5 +2,5 @@
# SPDX-License-Identifier: LGPL-2.1+
local -a _output_opts
_output_opts=(short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat)
_output_opts=(short short-full short-iso short-iso-precise short-precise short-monotonic short-unix verbose export json json-pretty json-sse cat with-unit)
_describe -t output 'output mode' _output_opts || compadd "$@"

View File

@ -334,7 +334,7 @@ static void help(void) {
" -o --output=STRING Change journal output mode (short, short-precise,\n"
" short-iso, short-iso-precise, short-full,\n"
" short-monotonic, short-unix, verbose, export,\n"
" json, json-pretty, json-sse, cat)\n"
" json, json-pretty, json-sse, cat, with-unit)\n"
" --output-fields=LIST Select fields to print in verbose/export/json modes\n"
" --utc Express time in Coordinated Universal Time (UTC)\n"
" -x --catalog Add message explanations where available\n"

View File

@ -306,7 +306,7 @@ static int output_timestamp_realtime(FILE *f, sd_journal *j, OutputMode mode, Ou
return -EINVAL;
}
if (mode == OUTPUT_SHORT_FULL) {
if (IN_SET(mode, OUTPUT_SHORT_FULL, OUTPUT_WITH_UNIT)) {
const char *k;
if (flags & OUTPUT_UTC)
@ -391,8 +391,8 @@ static int output_short(
const void *data;
size_t length;
size_t n = 0;
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0;
_cleanup_free_ char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = NULL, *priority = NULL, *unit = NULL, *user_unit = NULL;
size_t hostname_len = 0, identifier_len = 0, comm_len = 0, pid_len = 0, fake_pid_len = 0, message_len = 0, realtime_len = 0, monotonic_len = 0, priority_len = 0, unit_len = 0, user_unit_len = 0;
int p = LOG_INFO;
bool ellipsized = false;
const ParseFieldVec fields[] = {
@ -405,6 +405,8 @@ static int output_short(
PARSE_FIELD_VEC_ENTRY("SYSLOG_IDENTIFIER=", &identifier, &identifier_len),
PARSE_FIELD_VEC_ENTRY("_SOURCE_REALTIME_TIMESTAMP=", &realtime, &realtime_len),
PARSE_FIELD_VEC_ENTRY("_SOURCE_MONOTONIC_TIMESTAMP=", &monotonic, &monotonic_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_UNIT=", &unit, &unit_len),
PARSE_FIELD_VEC_ENTRY("_SYSTEMD_USER_UNIT=", &user_unit, &user_unit_len),
};
size_t highlight_shifted[] = {highlight ? highlight[0] : 0, highlight ? highlight[1] : 0};
@ -462,7 +464,19 @@ static int output_short(
n += hostname_len + 1;
}
if (identifier && shall_print(identifier, identifier_len, flags)) {
if (mode == OUTPUT_WITH_UNIT && ((unit && shall_print(unit, unit_len, flags)) || (user_unit && shall_print(user_unit, user_unit_len, flags)))) {
if (unit) {
fprintf(f, " %.*s", (int) unit_len, unit);
n += unit_len + 1;
}
if (user_unit) {
if (unit)
fprintf(f, "/%.*s", (int) user_unit_len, user_unit);
else
fprintf(f, " %.*s", (int) user_unit_len, user_unit);
n += unit_len + 1;
}
} else if (identifier && shall_print(identifier, identifier_len, flags)) {
fprintf(f, " %.*s", (int) identifier_len, identifier);
n += identifier_len + 1;
} else if (comm && shall_print(comm, comm_len, flags)) {
@ -1053,7 +1067,8 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(
[OUTPUT_JSON] = output_json,
[OUTPUT_JSON_PRETTY] = output_json,
[OUTPUT_JSON_SSE] = output_json,
[OUTPUT_CAT] = output_cat
[OUTPUT_CAT] = output_cat,
[OUTPUT_WITH_UNIT] = output_short,
};
int output_journal(

View File

@ -21,7 +21,8 @@ static const char *const output_mode_table[_OUTPUT_MODE_MAX] = {
[OUTPUT_JSON] = "json",
[OUTPUT_JSON_PRETTY] = "json-pretty",
[OUTPUT_JSON_SSE] = "json-sse",
[OUTPUT_CAT] = "cat"
[OUTPUT_CAT] = "cat",
[OUTPUT_WITH_UNIT] = "with-unit",
};
DEFINE_STRING_TABLE_LOOKUP(output_mode, OutputMode);

View File

@ -23,6 +23,7 @@ typedef enum OutputMode {
OUTPUT_JSON_PRETTY,
OUTPUT_JSON_SSE,
OUTPUT_CAT,
OUTPUT_WITH_UNIT,
_OUTPUT_MODE_MAX,
_OUTPUT_MODE_INVALID = -1
} OutputMode;