]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
journalctl: add --truncate-newline option
authorzhmylove <zhmylove@narod.ru>
Tue, 30 Aug 2022 15:50:19 +0000 (18:50 +0300)
committerLennart Poettering <lennart@poettering.net>
Fri, 16 Jun 2023 07:31:47 +0000 (09:31 +0200)
man/journalctl.xml
src/basic/string-util.c
src/basic/string-util.h
src/journal/journalctl.c
src/shared/logs-show.c
src/shared/output-mode.h
test/TEST-04-JOURNAL/test.sh
test/units/testsuite-04.journal.sh

index d54937a220422a3f2654527da32c52c6076215d0..d52f0e15c52089ff7e70efd6308729d3e4d06c2b 100644 (file)
             precision.</para></listitem>
           </varlistentry>
 
+          <varlistentry>
+            <term><option>--truncate-newline</option></term>
+
+            <listitem><para>Truncate each log message at the first newline character on output, so that only the
+            first line of each message is displayed.</para></listitem>
+          </varlistentry>
+
           <varlistentry>
             <term><option>short-precise</option></term>
             <listitem><para>is very similar, but shows classic syslog timestamps with full microsecond
index 5d259cbf81856fd732813ff09783a0ad8f0a4b34..41d264318a27f4dd99bd789580726b0f91d305a5 100644 (file)
@@ -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;
 }
 
index 4430910e225857a741fb750b1738baa80e37a95d..b5028c9e00080ac0c026a2bab0ee902353e62703 100644 (file)
@@ -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)
index ab7760290aba631168127e118d5c5234c25bb768..f4180a9a7fda61bbd625757084d3b1bdf7cac55d 100644 (file)
@@ -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,
index e0b85588bb2f1d69e609032626a5eab297b68b55..f467d844aa43fd01f9ef74410ca511de726afcdc 100644 (file)
@@ -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';
 
index 26351c9fdb98fcfe183c94457d6dfbb3ee4675e1..8683f573af1e3dff04ea67e6c052ee3d58733fc7 100644 (file)
@@ -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);
index 507dace51492e1a464ca7cf0c1dc35c76a142182..09516d11f5a976be7883c4901845cf33b77761d1 100755 (executable)
@@ -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 "$@"
index 0078013654c3aab5fe6736749bcb64be014ed6d2..58c3661391c80ac299f62c52befc8971521ce8d1 100755 (executable)
@@ -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