449 lines
16 KiB
Diff
449 lines
16 KiB
Diff
|
From 1682c4bf5b993b956b0367aedc9f0638055540f4 Mon Sep 17 00:00:00 2001
|
||
|
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
|
||
|
Date: Thu, 19 Jul 2012 21:12:16 +0000
|
||
|
Subject: [PATCH 1/3] journalctl: fix assertion failure in ellipsize_mem()
|
||
|
|
||
|
When showing the journal through "journalctl --no-pager", if the
|
||
|
prefix of the log message (i.e. the date and syslog identifier) is
|
||
|
less than 3 characters shorter than the width of the terminal, you
|
||
|
get:
|
||
|
|
||
|
Assertion 'new_length >= 3' failed at src/shared/util.c:3859, function ellipsize_mem(). Aborting.
|
||
|
|
||
|
because there is not enough space for the "...". This patch add the
|
||
|
necessary check.
|
||
|
---
|
||
|
src/logs-show.c | 2 +-
|
||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/src/logs-show.c b/src/logs-show.c
|
||
|
index eb9a902..72367f2 100644
|
||
|
--- a/src/logs-show.c
|
||
|
+++ b/src/logs-show.c
|
||
|
@@ -230,7 +230,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
|
||
|
printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
|
||
|
} else if (message_len + n < n_columns)
|
||
|
printf(": %.*s\n", (int) message_len, message);
|
||
|
- else if (n < n_columns) {
|
||
|
+ else if (n < n_columns && n_columns - n - 2 >= 3) {
|
||
|
char *e;
|
||
|
|
||
|
e = ellipsize_mem(message, message_len, n_columns - n - 2, 90);
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|
||
|
|
||
|
From ee385756e10862a8bcc0e5c7a3776135af84c750 Mon Sep 17 00:00:00 2001
|
||
|
From: Zbigniew Jedrzejewski-Szmek <zbyszek@in.waw.pl>
|
||
|
Date: Fri, 20 Jul 2012 09:06:26 +0200
|
||
|
Subject: [PATCH 2/3] journalctl: fix ellipsization with PAGER=cat
|
||
|
|
||
|
There are other reasons for not opening the pager then the --no-pager
|
||
|
or --follow options (described below). If the pager is not used,
|
||
|
messages must be ellipsized.
|
||
|
|
||
|
On Fri, Jul 20, 2012 at 05:42:44AM +0000, Shawn Landen wrote:
|
||
|
> "Pager to use when --no-pager is not given; overrides $PAGER.
|
||
|
> Setting this to an empty string or the value cat is equivalent to passing --no-pager."
|
||
|
|
||
|
Conflicts:
|
||
|
src/journal/journalctl.c
|
||
|
---
|
||
|
src/journal/journalctl.c | 5 +----
|
||
|
src/pager.c | 17 ++++++++++-------
|
||
|
src/pager.h | 4 +++-
|
||
|
3 files changed, 14 insertions(+), 12 deletions(-)
|
||
|
|
||
|
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
|
||
|
index f90b2dd..3a3b043 100644
|
||
|
--- a/src/journal/journalctl.c
|
||
|
+++ b/src/journal/journalctl.c
|
||
|
@@ -259,10 +259,7 @@ int main(int argc, char *argv[]) {
|
||
|
goto finish;
|
||
|
}
|
||
|
|
||
|
- if (!arg_no_pager && !arg_follow) {
|
||
|
- columns();
|
||
|
- pager_open();
|
||
|
- }
|
||
|
+ have_pager = !arg_no_pager && !arg_follow && pager_open();
|
||
|
|
||
|
if (arg_output == OUTPUT_JSON) {
|
||
|
fputc('[', stdout);
|
||
|
diff --git a/src/pager.c b/src/pager.c
|
||
|
index 3fc8182..8065841 100644
|
||
|
--- a/src/pager.c
|
||
|
+++ b/src/pager.c
|
||
|
@@ -44,20 +44,20 @@ _noreturn_ static void pager_fallback(void) {
|
||
|
_exit(EXIT_SUCCESS);
|
||
|
}
|
||
|
|
||
|
-void pager_open(void) {
|
||
|
+bool pager_open(void) {
|
||
|
int fd[2];
|
||
|
const char *pager;
|
||
|
pid_t parent_pid;
|
||
|
|
||
|
if (pager_pid > 0)
|
||
|
- return;
|
||
|
+ return false;
|
||
|
|
||
|
if ((pager = getenv("SYSTEMD_PAGER")) || (pager = getenv("PAGER")))
|
||
|
if (!*pager || streq(pager, "cat"))
|
||
|
- return;
|
||
|
+ return false;
|
||
|
|
||
|
if (isatty(STDOUT_FILENO) <= 0)
|
||
|
- return;
|
||
|
+ return false;
|
||
|
|
||
|
/* Determine and cache number of columns before we spawn the
|
||
|
* pager so that we get the value from the actual tty */
|
||
|
@@ -65,7 +65,7 @@ void pager_open(void) {
|
||
|
|
||
|
if (pipe(fd) < 0) {
|
||
|
log_error("Failed to create pager pipe: %m");
|
||
|
- return;
|
||
|
+ return false;
|
||
|
}
|
||
|
|
||
|
parent_pid = getpid();
|
||
|
@@ -74,7 +74,7 @@ void pager_open(void) {
|
||
|
if (pager_pid < 0) {
|
||
|
log_error("Failed to fork pager: %m");
|
||
|
close_pipe(fd);
|
||
|
- return;
|
||
|
+ return false;
|
||
|
}
|
||
|
|
||
|
/* In the child start the pager */
|
||
|
@@ -115,10 +115,13 @@ void pager_open(void) {
|
||
|
}
|
||
|
|
||
|
/* Return in the parent */
|
||
|
- if (dup2(fd[1], STDOUT_FILENO) < 0)
|
||
|
+ if (dup2(fd[1], STDOUT_FILENO) < 0) {
|
||
|
log_error("Failed to duplicate pager pipe: %m");
|
||
|
+ return false;
|
||
|
+ }
|
||
|
|
||
|
close_pipe(fd);
|
||
|
+ return true;
|
||
|
}
|
||
|
|
||
|
void pager_close(void) {
|
||
|
diff --git a/src/pager.h b/src/pager.h
|
||
|
index b5b4998..bd1a983 100644
|
||
|
--- a/src/pager.h
|
||
|
+++ b/src/pager.h
|
||
|
@@ -22,7 +22,9 @@
|
||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||
|
***/
|
||
|
|
||
|
-void pager_open(void);
|
||
|
+#include <stdbool.h>
|
||
|
+
|
||
|
+bool pager_open(void);
|
||
|
void pager_close(void);
|
||
|
|
||
|
#endif
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|
||
|
|
||
|
From ae88e07aec6280e90582703f7950468604182a4b Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
||
|
Date: Tue, 17 Jul 2012 07:35:08 +0200
|
||
|
Subject: [PATCH 3/3] journalctl: do not ellipsize when using pager
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
If a pager is used, ellipsization is redundant — the pager does
|
||
|
that better by hiding the part that cannot be shown. Pager's advantage
|
||
|
is that the user can press → to view the hidden part of a message,
|
||
|
and then ← to return.
|
||
|
|
||
|
cherry-picked from 92a1fd9e95954a557d6fe27b56f5ef1b89fc2f5e and 25277cd7fbd77e4c8b20572570aa77c7da9abcc2
|
||
|
---
|
||
|
src/journal/journalctl.c | 7 ++++-
|
||
|
src/logs-show.c | 66 ++++++++++++++++++++++++++++------------------
|
||
|
src/logs-show.h | 14 +++++++---
|
||
|
src/systemctl.c | 8 +++++-
|
||
|
4 files changed, 64 insertions(+), 31 deletions(-)
|
||
|
|
||
|
diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c
|
||
|
index 3a3b043..197af71 100644
|
||
|
--- a/src/journal/journalctl.c
|
||
|
+++ b/src/journal/journalctl.c
|
||
|
@@ -198,6 +198,7 @@ int main(int argc, char *argv[]) {
|
||
|
sd_journal *j = NULL;
|
||
|
unsigned line = 0;
|
||
|
bool need_seek = false;
|
||
|
+ bool have_pager;
|
||
|
|
||
|
log_parse_environment();
|
||
|
log_open();
|
||
|
@@ -268,6 +269,10 @@ int main(int argc, char *argv[]) {
|
||
|
|
||
|
for (;;) {
|
||
|
for (;;) {
|
||
|
+ int flags =
|
||
|
+ arg_show_all * OUTPUT_SHOW_ALL |
|
||
|
+ have_pager * OUTPUT_FULL_WIDTH;
|
||
|
+
|
||
|
if (need_seek) {
|
||
|
r = sd_journal_next(j);
|
||
|
if (r < 0) {
|
||
|
@@ -281,7 +286,7 @@ int main(int argc, char *argv[]) {
|
||
|
|
||
|
line ++;
|
||
|
|
||
|
- r = output_journal(j, arg_output, line, 0, arg_show_all);
|
||
|
+ r = output_journal(j, arg_output, line, 0, flags);
|
||
|
if (r < 0)
|
||
|
goto finish;
|
||
|
|
||
|
diff --git a/src/logs-show.c b/src/logs-show.c
|
||
|
index 72367f2..06ba569 100644
|
||
|
--- a/src/logs-show.c
|
||
|
+++ b/src/logs-show.c
|
||
|
@@ -86,7 +86,8 @@ static bool shall_print(bool show_all, char *p, size_t l) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
-static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool show_all, bool monotonic_mode) {
|
||
|
+static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
|
||
|
+ OutputFlags flags) {
|
||
|
int r;
|
||
|
const void *data;
|
||
|
size_t length;
|
||
|
@@ -150,7 +151,7 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
|
||
|
goto finish;
|
||
|
}
|
||
|
|
||
|
- if (monotonic_mode) {
|
||
|
+ if (flags & OUTPUT_MONOTONIC_MODE) {
|
||
|
uint64_t t;
|
||
|
sd_id128_t boot_id;
|
||
|
|
||
|
@@ -202,33 +203,39 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns, bool s
|
||
|
n += strlen(buf);
|
||
|
}
|
||
|
|
||
|
- if (hostname && shall_print(show_all, hostname, hostname_len)) {
|
||
|
+ if (hostname && shall_print(flags & OUTPUT_SHOW_ALL,
|
||
|
+ hostname, hostname_len)) {
|
||
|
printf(" %.*s", (int) hostname_len, hostname);
|
||
|
n += hostname_len + 1;
|
||
|
}
|
||
|
|
||
|
- if (identifier && shall_print(show_all, identifier, identifier_len)) {
|
||
|
+ if (identifier && shall_print(flags & OUTPUT_SHOW_ALL,
|
||
|
+ identifier, identifier_len)) {
|
||
|
printf(" %.*s", (int) identifier_len, identifier);
|
||
|
n += identifier_len + 1;
|
||
|
- } else if (comm && shall_print(show_all, comm, comm_len)) {
|
||
|
+ } else if (comm && shall_print(flags & OUTPUT_SHOW_ALL,
|
||
|
+ comm, comm_len)) {
|
||
|
printf(" %.*s", (int) comm_len, comm);
|
||
|
n += comm_len + 1;
|
||
|
- }
|
||
|
+ } else
|
||
|
+ putchar(' ');
|
||
|
|
||
|
- if (pid && shall_print(show_all, pid, pid_len)) {
|
||
|
+ if (pid && shall_print(flags & OUTPUT_SHOW_ALL, pid, pid_len)) {
|
||
|
printf("[%.*s]", (int) pid_len, pid);
|
||
|
n += pid_len + 2;
|
||
|
- } else if (fake_pid && shall_print(show_all, fake_pid, fake_pid_len)) {
|
||
|
+ } else if (fake_pid && shall_print(flags & OUTPUT_SHOW_ALL,
|
||
|
+ fake_pid, fake_pid_len)) {
|
||
|
printf("[%.*s]", (int) fake_pid_len, fake_pid);
|
||
|
n += fake_pid_len + 2;
|
||
|
}
|
||
|
|
||
|
- if (show_all)
|
||
|
+ if (flags & OUTPUT_SHOW_ALL)
|
||
|
printf(": %.*s\n", (int) message_len, message);
|
||
|
else if (contains_unprintable(message, message_len)) {
|
||
|
char bytes[FORMAT_BYTES_MAX];
|
||
|
printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
|
||
|
- } else if (message_len + n < n_columns)
|
||
|
+ } else if ((flags & OUTPUT_FULL_WIDTH) ||
|
||
|
+ (message_len + n + 1 < n_columns))
|
||
|
printf(": %.*s\n", (int) message_len, message);
|
||
|
else if (n < n_columns && n_columns - n - 2 >= 3) {
|
||
|
char *e;
|
||
|
@@ -259,15 +266,18 @@ finish:
|
||
|
return r;
|
||
|
}
|
||
|
|
||
|
-static int output_short_realtime(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
- return output_short(j, line, n_columns, show_all, false);
|
||
|
+static int output_short_realtime(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
+ return output_short(j, line, n_columns, flags & ~OUTPUT_MONOTONIC_MODE);
|
||
|
}
|
||
|
|
||
|
-static int output_short_monotonic(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
- return output_short(j, line, n_columns, show_all, true);
|
||
|
+static int output_short_monotonic(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
+ return output_short(j, line, n_columns, flags | OUTPUT_MONOTONIC_MODE);
|
||
|
}
|
||
|
|
||
|
-static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
+static int output_verbose(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
const void *data;
|
||
|
size_t length;
|
||
|
char *cursor;
|
||
|
@@ -296,7 +306,7 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool
|
||
|
free(cursor);
|
||
|
|
||
|
SD_JOURNAL_FOREACH_DATA(j, data, length) {
|
||
|
- if (!show_all && (length > PRINT_THRESHOLD ||
|
||
|
+ if (!(flags & OUTPUT_SHOW_ALL) && (length > PRINT_THRESHOLD ||
|
||
|
contains_unprintable(data, length))) {
|
||
|
const char *c;
|
||
|
char bytes[FORMAT_BYTES_MAX];
|
||
|
@@ -318,7 +328,8 @@ static int output_verbose(sd_journal *j, unsigned line, unsigned n_columns, bool
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static int output_export(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
+static int output_export(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
sd_id128_t boot_id;
|
||
|
char sid[33];
|
||
|
int r;
|
||
|
@@ -424,7 +435,8 @@ static void json_escape(const char* p, size_t l) {
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
+static int output_json(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
uint64_t realtime, monotonic;
|
||
|
char *cursor;
|
||
|
const void *data;
|
||
|
@@ -491,7 +503,8 @@ static int output_json(sd_journal *j, unsigned line, unsigned n_columns, bool sh
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
+static int output_cat(sd_journal *j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
const void *data;
|
||
|
size_t l;
|
||
|
int r;
|
||
|
@@ -512,7 +525,8 @@ static int output_cat(sd_journal *j, unsigned line, unsigned n_columns, bool sho
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
-static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsigned n_columns, bool show_all) = {
|
||
|
+static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) = {
|
||
|
[OUTPUT_SHORT] = output_short_realtime,
|
||
|
[OUTPUT_SHORT_MONOTONIC] = output_short_monotonic,
|
||
|
[OUTPUT_VERBOSE] = output_verbose,
|
||
|
@@ -521,14 +535,15 @@ static int (*output_funcs[_OUTPUT_MODE_MAX])(sd_journal*j, unsigned line, unsign
|
||
|
[OUTPUT_CAT] = output_cat
|
||
|
};
|
||
|
|
||
|
-int output_journal(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns, bool show_all) {
|
||
|
+int output_journal(sd_journal *j, OutputMode mode, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags) {
|
||
|
assert(mode >= 0);
|
||
|
assert(mode < _OUTPUT_MODE_MAX);
|
||
|
|
||
|
if (n_columns <= 0)
|
||
|
n_columns = columns();
|
||
|
|
||
|
- return output_funcs[mode](j, line, n_columns, show_all);
|
||
|
+ return output_funcs[mode](j, line, n_columns, flags);
|
||
|
}
|
||
|
|
||
|
int show_journal_by_unit(
|
||
|
@@ -537,8 +552,7 @@ int show_journal_by_unit(
|
||
|
unsigned n_columns,
|
||
|
usec_t not_before,
|
||
|
unsigned how_many,
|
||
|
- bool show_all,
|
||
|
- bool follow) {
|
||
|
+ OutputFlags flags) {
|
||
|
|
||
|
char *m = NULL;
|
||
|
sd_journal *j = NULL;
|
||
|
@@ -621,12 +635,12 @@ int show_journal_by_unit(
|
||
|
|
||
|
line ++;
|
||
|
|
||
|
- r = output_journal(j, mode, line, n_columns, show_all);
|
||
|
+ r = output_journal(j, mode, line, n_columns, flags);
|
||
|
if (r < 0)
|
||
|
goto finish;
|
||
|
}
|
||
|
|
||
|
- if (!follow)
|
||
|
+ if (!(flags & OUTPUT_FOLLOW))
|
||
|
break;
|
||
|
|
||
|
r = fd_wait_for_event(fd, POLLIN, (usec_t) -1);
|
||
|
diff --git a/src/logs-show.h b/src/logs-show.h
|
||
|
index db9c7e3..e8c6b03 100644
|
||
|
--- a/src/logs-show.h
|
||
|
+++ b/src/logs-show.h
|
||
|
@@ -39,7 +39,16 @@ typedef enum OutputMode {
|
||
|
_OUTPUT_MODE_INVALID = -1
|
||
|
} OutputMode;
|
||
|
|
||
|
-int output_journal(sd_journal *j, OutputMode mode, unsigned line, unsigned n_columns, bool show_all);
|
||
|
+typedef enum OutputFlags {
|
||
|
+ OUTPUT_SHOW_ALL = 1 << 0,
|
||
|
+ OUTPUT_MONOTONIC_MODE = 1 << 1,
|
||
|
+ OUTPUT_FOLLOW = 1 << 2,
|
||
|
+ OUTPUT_WARN_CUTOFF = 1 << 3,
|
||
|
+ OUTPUT_FULL_WIDTH = 1 << 4,
|
||
|
+} OutputFlags;
|
||
|
+
|
||
|
+int output_journal(sd_journal *j, OutputMode mode, unsigned line,
|
||
|
+ unsigned n_columns, OutputFlags flags);
|
||
|
|
||
|
int show_journal_by_unit(
|
||
|
const char *unit,
|
||
|
@@ -47,8 +56,7 @@ int show_journal_by_unit(
|
||
|
unsigned n_columns,
|
||
|
usec_t not_before,
|
||
|
unsigned how_many,
|
||
|
- bool show_all,
|
||
|
- bool follow);
|
||
|
+ OutputFlags flags);
|
||
|
|
||
|
const char* output_mode_to_string(OutputMode m);
|
||
|
OutputMode output_mode_from_string(const char *s);
|
||
|
diff --git a/src/systemctl.c b/src/systemctl.c
|
||
|
index f51085f..e94e024 100644
|
||
|
--- a/src/systemctl.c
|
||
|
+++ b/src/systemctl.c
|
||
|
@@ -2374,8 +2374,14 @@ static void print_status_info(UnitStatusInfo *i) {
|
||
|
}
|
||
|
|
||
|
if (i->id && arg_transport != TRANSPORT_SSH) {
|
||
|
+ int flags =
|
||
|
+ arg_lines * OUTPUT_SHOW_ALL |
|
||
|
+ arg_follow * OUTPUT_FOLLOW;
|
||
|
+
|
||
|
printf("\n");
|
||
|
- show_journal_by_unit(i->id, arg_output, 0, i->inactive_exit_timestamp_monotonic, arg_lines, arg_all, arg_follow);
|
||
|
+ show_journal_by_unit(i->id, arg_output, 0,
|
||
|
+ i->inactive_exit_timestamp_monotonic,
|
||
|
+ arg_lines, flags);
|
||
|
}
|
||
|
|
||
|
if (i->need_daemon_reload)
|
||
|
--
|
||
|
1.7.10.4
|
||
|
|