From: zhmylove Date: Tue, 30 Aug 2022 15:50:19 +0000 (+0300) Subject: journalctl: add --truncate-newline option X-Git-Tag: v254-rc1~190 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=61cecfa0d8b3ee41ebd493b255b8201653d51b98;p=thirdparty%2Fsystemd.git journalctl: add --truncate-newline option --- diff --git a/man/journalctl.xml b/man/journalctl.xml index d54937a2204..d52f0e15c52 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -429,6 +429,13 @@ precision. + + + + Truncate each log message at the first newline character on output, so that only the + first line of each message is displayed. + + is very similar, but shows classic syslog timestamps with full microsecond diff --git a/src/basic/string-util.c b/src/basic/string-util.c index 5d259cbf818..41d264318a2 100644 --- a/src/basic/string-util.c +++ b/src/basic/string-util.c @@ -170,10 +170,15 @@ char *delete_trailing_chars(char *s, const char *bad) { return s; } -char *truncate_nl(char *s) { +char *truncate_nl_full(char *s, size_t *ret_len) { + size_t n; + assert(s); - s[strcspn(s, NEWLINE)] = 0; + n = strcspn(s, NEWLINE); + s[n] = '\0'; + if (ret_len) + *ret_len = n; return s; } diff --git a/src/basic/string-util.h b/src/basic/string-util.h index 4430910e225..b5028c9e000 100644 --- a/src/basic/string-util.h +++ b/src/basic/string-util.h @@ -121,7 +121,10 @@ char *strjoin_real(const char *x, ...) _sentinel_; char *strstrip(char *s); char *delete_chars(char *s, const char *bad); char *delete_trailing_chars(char *s, const char *bad); -char *truncate_nl(char *s); +char *truncate_nl_full(char *s, size_t *ret_len); +static inline char *truncate_nl(char *s) { + return truncate_nl_full(s, NULL); +} static inline char *skip_leading_chars(const char *s, const char *bad) { if (!s) diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index ab7760290ab..f4180a9a7fd 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -96,6 +96,7 @@ static bool arg_all = false; static PagerFlags arg_pager_flags = 0; static int arg_lines = ARG_LINES_DEFAULT; static bool arg_no_tail = false; +static bool arg_truncate_newline = false; static bool arg_quiet = false; static bool arg_merge = false; static bool arg_boot = false; @@ -367,6 +368,7 @@ static int help(void) { " -a --all Show all fields, including long and unprintable\n" " -f --follow Follow the journal\n" " --no-tail Show all lines, even in follow mode\n" + " --truncate-newline Truncate entries by first newline character\n" " -q --quiet Do not show info messages and privilege warning\n" "\n%3$sPager Control Options:%4$s\n" " --no-pager Do not pipe output into a pager\n" @@ -445,6 +447,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_RELINQUISH_VAR, ARG_SMART_RELINQUISH_VAR, ARG_ROTATE, + ARG_TRUNCATE_NEWLINE, ARG_VACUUM_SIZE, ARG_VACUUM_FILES, ARG_VACUUM_TIME, @@ -465,6 +468,7 @@ static int parse_argv(int argc, char *argv[]) { { "full", no_argument, NULL, 'l' }, { "no-full", no_argument, NULL, ARG_NO_FULL }, { "lines", optional_argument, NULL, 'n' }, + { "truncate-newline", no_argument, NULL, ARG_TRUNCATE_NEWLINE }, { "no-tail", no_argument, NULL, ARG_NO_TAIL }, { "new-id128", no_argument, NULL, ARG_NEW_ID128 }, /* deprecated */ { "quiet", no_argument, NULL, 'q' }, @@ -622,6 +626,10 @@ static int parse_argv(int argc, char *argv[]) { arg_no_tail = true; break; + case ARG_TRUNCATE_NEWLINE: + arg_truncate_newline = true; + break; + case ARG_NEW_ID128: arg_action = ACTION_NEW_ID128; break; @@ -2229,6 +2237,7 @@ static int show(Context *c) { colors_enabled() * OUTPUT_COLOR | arg_catalog * OUTPUT_CATALOG | arg_utc * OUTPUT_UTC | + arg_truncate_newline * OUTPUT_TRUNCATE_NEWLINE | arg_no_hostname * OUTPUT_NO_HOSTNAME; r = show_journal_entry(stdout, j, arg_output, 0, flags, diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index e0b85588bb2..f467d844aa4 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -524,6 +524,9 @@ static int output_short( if (!(flags & OUTPUT_SHOW_ALL)) strip_tab_ansi(&message, &message_len, highlight_shifted); + if (flags & OUTPUT_TRUNCATE_NEWLINE) + truncate_nl_full(message, &message_len); + if (priority_len == 1 && *priority >= '0' && *priority <= '7') p = *priority - '0'; diff --git a/src/shared/output-mode.h b/src/shared/output-mode.h index 26351c9fdb9..8683f573af1 100644 --- a/src/shared/output-mode.h +++ b/src/shared/output-mode.h @@ -33,21 +33,22 @@ static inline bool OUTPUT_MODE_IS_JSON(OutputMode m) { * logs output, others only to the process tree output. */ typedef enum OutputFlags { - OUTPUT_SHOW_ALL = 1 << 0, - OUTPUT_FULL_WIDTH = 1 << 1, - OUTPUT_COLOR = 1 << 2, + OUTPUT_SHOW_ALL = 1 << 0, + OUTPUT_FULL_WIDTH = 1 << 1, + OUTPUT_COLOR = 1 << 2, /* Specific to log output */ - OUTPUT_WARN_CUTOFF = 1 << 3, - OUTPUT_CATALOG = 1 << 4, - OUTPUT_BEGIN_NEWLINE = 1 << 5, - OUTPUT_UTC = 1 << 6, - OUTPUT_NO_HOSTNAME = 1 << 7, + OUTPUT_WARN_CUTOFF = 1 << 3, + OUTPUT_CATALOG = 1 << 4, + OUTPUT_BEGIN_NEWLINE = 1 << 5, + OUTPUT_UTC = 1 << 6, + OUTPUT_NO_HOSTNAME = 1 << 7, + OUTPUT_TRUNCATE_NEWLINE = 1 << 8, /* Specific to process tree output */ - OUTPUT_KERNEL_THREADS = 1 << 8, - OUTPUT_CGROUP_XATTRS = 1 << 9, - OUTPUT_CGROUP_ID = 1 << 10, + OUTPUT_KERNEL_THREADS = 1 << 9, + OUTPUT_CGROUP_XATTRS = 1 << 10, + OUTPUT_CGROUP_ID = 1 << 11, } OutputFlags; JsonFormatFlags output_mode_to_json_format_flags(OutputMode m); diff --git a/test/TEST-04-JOURNAL/test.sh b/test/TEST-04-JOURNAL/test.sh index 507dace5149..09516d11f5a 100755 --- a/test/TEST-04-JOURNAL/test.sh +++ b/test/TEST-04-JOURNAL/test.sh @@ -14,6 +14,10 @@ test_append_files() { cp -av "${TEST_BASE_DIR:?}/test-journals/"* "$workspace/test-journals/" inst_binary unzstd + + ( + command -v logger >/dev/null 2>&1 && inst_binary logger + ) } do_test "$@" diff --git a/test/units/testsuite-04.journal.sh b/test/units/testsuite-04.journal.sh index 0078013654c..58c3661391c 100755 --- a/test/units/testsuite-04.journal.sh +++ b/test/units/testsuite-04.journal.sh @@ -51,6 +51,17 @@ grep -q '^PRIORITY=6$' /tmp/output (! grep '^FOO=' /tmp/output) (! grep '^SYSLOG_FACILITY=' /tmp/output) +# --truncate shows only first line, skip under asan due to logger +if [ -z "${ASAN_OPTIONS+x}${UBSAN_OPTIONS+x}" ] && command -v logger >/dev/null 2>&1 ;then + ID=$(journalctl --new-id128 | sed -n 2p) + logger -t "$ID" $'HEAD\nTAIL\nTAIL' + journalctl --sync + journalctl -q -b -t "$ID" | grep -q HEAD + journalctl -q -b -t "$ID" | grep -q TAIL + journalctl -q -b -t "$ID" --truncate-newline | grep -q HEAD + journalctl -q -b -t "$ID" --truncate-newline | grep -q -v TAIL +fi + # '-b all' negates earlier use of -b (-b and -m are otherwise exclusive) journalctl -b -1 -b all -m >/dev/null