chiark / gitweb /
journalctl: hightlight log lines by priority
authorLennart Poettering <lennart@poettering.net>
Thu, 26 Jul 2012 14:50:35 +0000 (16:50 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 26 Jul 2012 14:56:21 +0000 (16:56 +0200)
warn/notice = bright white
< error = red

src/journal/journalctl.c
src/shared/logs-show.c
src/shared/logs-show.h
src/systemctl/systemctl.c

index c924afbccc8953273509f045bdb38ee95f41ce18..abcfabe75d4e56d02b7f2d1b1a72c85081195638 100644 (file)
@@ -198,6 +198,21 @@ static int parse_argv(int argc, char *argv[]) {
         return 1;
 }
 
         return 1;
 }
 
+static bool on_tty(void) {
+        static int t = -1;
+
+        /* Note that this is invoked relatively early, before we start
+         * the pager. That means the value we return reflects whether
+         * we originally were started on a tty, not if we currently
+         * are. But this is intended, since we want colour and so on
+         * when run in our own pager. */
+
+        if (_unlikely_(t < 0))
+                t = isatty(STDOUT_FILENO) > 0;
+
+        return t;
+}
+
 static int generate_new_id128(void) {
         sd_id128_t id;
         int r;
 static int generate_new_id128(void) {
         sd_id128_t id;
         int r;
@@ -397,6 +412,7 @@ int main(int argc, char *argv[]) {
                 goto finish;
         }
 
                 goto finish;
         }
 
+        on_tty();
         have_pager = !arg_no_pager && !arg_follow && pager_open();
 
         if (arg_output == OUTPUT_JSON) {
         have_pager = !arg_no_pager && !arg_follow && pager_open();
 
         if (arg_output == OUTPUT_JSON) {
@@ -407,8 +423,10 @@ int main(int argc, char *argv[]) {
         for (;;) {
                 for (;;) {
                         sd_id128_t boot_id;
         for (;;) {
                 for (;;) {
                         sd_id128_t boot_id;
-                        int flags = (arg_show_all*OUTPUT_SHOW_ALL |
-                                     have_pager*OUTPUT_FULL_WIDTH);
+                        int flags =
+                                arg_show_all * OUTPUT_SHOW_ALL |
+                                have_pager * OUTPUT_FULL_WIDTH |
+                                on_tty() * OUTPUT_COLOR;
 
                         if (need_seek) {
                                 r = sd_journal_next(j);
 
                         if (need_seek) {
                                 r = sd_journal_next(j);
index 375ca543c1e8ed99a7d63cc1f0aa54b1194ace11..c72ebc11f57c1644ec777249299b5d31c0fba737 100644 (file)
@@ -82,13 +82,21 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
         const void *data;
         size_t length;
         size_t n = 0;
         const void *data;
         size_t length;
         size_t n = 0;
-        char *hostname = NULL, *identifier = NULL, *comm = NULL, *pid = NULL, *fake_pid = NULL, *message = NULL, *realtime = NULL, *monotonic = 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;
+        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;
+        int p = LOG_INFO;
+        const char *color_on = "", *color_off = "";
 
         assert(j);
 
         SD_JOURNAL_FOREACH_DATA(j, data, length) {
 
 
         assert(j);
 
         SD_JOURNAL_FOREACH_DATA(j, data, length) {
 
+                r = parse_field(data, length, "PRIORITY=", &priority, &priority_len);
+                if (r < 0)
+                        goto finish;
+                else if (r > 0)
+                        continue;
+
                 r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len);
                 if (r < 0)
                         goto finish;
                 r = parse_field(data, length, "_HOSTNAME=", &hostname, &hostname_len);
                 if (r < 0)
                         goto finish;
@@ -141,6 +149,9 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
                 goto finish;
         }
 
                 goto finish;
         }
 
+        if (priority_len == 1 && *priority >= '0' && *priority <= '7')
+                p = *priority - '0';
+
         if (flags & OUTPUT_MONOTONIC_MODE) {
                 uint64_t t;
                 sd_id128_t boot_id;
         if (flags & OUTPUT_MONOTONIC_MODE) {
                 uint64_t t;
                 sd_id128_t boot_id;
@@ -219,23 +230,33 @@ static int output_short(sd_journal *j, unsigned line, unsigned n_columns,
                 n += fake_pid_len + 2;
         }
 
                 n += fake_pid_len + 2;
         }
 
+        if (flags & OUTPUT_COLOR) {
+                if (p <= LOG_ERR) {
+                        color_on = ANSI_HIGHLIGHT_RED_ON;
+                        color_off = ANSI_HIGHLIGHT_OFF;
+                } else if (p <= LOG_NOTICE) {
+                        color_on = ANSI_HIGHLIGHT_ON;
+                        color_off = ANSI_HIGHLIGHT_OFF;
+                }
+        }
+
         if (flags & OUTPUT_SHOW_ALL)
         if (flags & OUTPUT_SHOW_ALL)
-                printf(": %.*s\n", (int) message_len, message);
+                printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
         else if (!utf8_is_printable_n(message, message_len)) {
                 char bytes[FORMAT_BYTES_MAX];
                 printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
         } else if ((flags & OUTPUT_FULL_WIDTH) ||
                    (message_len + n < n_columns))
         else if (!utf8_is_printable_n(message, message_len)) {
                 char bytes[FORMAT_BYTES_MAX];
                 printf(": [%s blob data]\n", format_bytes(bytes, sizeof(bytes), message_len));
         } else if ((flags & OUTPUT_FULL_WIDTH) ||
                    (message_len + n < n_columns))
-                printf(": %.*s\n", (int) message_len, message);
+                printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
         else if (n < n_columns && n_columns - n - 2 >= 3) {
                 char *e;
 
                 e = ellipsize_mem(message, message_len, n_columns - n - 2, 90);
 
                 if (!e)
         else if (n < n_columns && n_columns - n - 2 >= 3) {
                 char *e;
 
                 e = ellipsize_mem(message, message_len, n_columns - n - 2, 90);
 
                 if (!e)
-                        printf(": %.*s\n", (int) message_len, message);
+                        printf(": %s%.*s%s\n", color_on, (int) message_len, message, color_off);
                 else
                 else
-                        printf(": %s\n", e);
+                        printf(": %s%s%s\n", color_on, e, color_off);
 
                 free(e);
         } else
 
                 free(e);
         } else
index 4e6743254bda9e0def1720ffa5d6a72fb1a19a57..58ff9e5760bd8b39101f07fc2f2ca2cf8cd1db39 100644 (file)
@@ -39,11 +39,12 @@ typedef enum OutputMode {
 } OutputMode;
 
 typedef enum OutputFlags {
 } OutputMode;
 
 typedef enum OutputFlags {
-        OUTPUT_SHOW_ALL = 1 << 0,
+        OUTPUT_SHOW_ALL       = 1 << 0,
         OUTPUT_MONOTONIC_MODE = 1 << 1,
         OUTPUT_MONOTONIC_MODE = 1 << 1,
-        OUTPUT_FOLLOW = 1 << 2,
-        OUTPUT_WARN_CUTOFF = 1 << 3,
-        OUTPUT_FULL_WIDTH = 1 << 4,
+        OUTPUT_FOLLOW         = 1 << 2,
+        OUTPUT_WARN_CUTOFF    = 1 << 3,
+        OUTPUT_FULL_WIDTH     = 1 << 4,
+        OUTPUT_COLOR          = 1 << 5
 } OutputFlags;
 
 int output_journal(sd_journal *j, OutputMode mode, unsigned line,
 } OutputFlags;
 
 int output_journal(sd_journal *j, OutputMode mode, unsigned line,
index ef8ab2dc1433ce5d7f6b94cfef35167c82a0544e..e74f18630dba56ef3eaefc9cc41b82b64c13e262 100644 (file)
@@ -2584,9 +2584,12 @@ static void print_status_info(UnitStatusInfo *i) {
         }
 
         if (i->id && arg_transport != TRANSPORT_SSH) {
         }
 
         if (i->id && arg_transport != TRANSPORT_SSH) {
-                int flags = (arg_lines*OUTPUT_SHOW_ALL |
-                             arg_follow*OUTPUT_FOLLOW |
-                             !arg_quiet*OUTPUT_WARN_CUTOFF);
+                int flags =
+                        arg_lines * OUTPUT_SHOW_ALL |
+                        arg_follow * OUTPUT_FOLLOW |
+                        !arg_quiet * OUTPUT_WARN_CUTOFF |
+                        on_tty() * OUTPUT_COLOR;
+
                 printf("\n");
                 show_journal_by_unit(i->id, arg_output, 0,
                                      i->inactive_exit_timestamp_monotonic,
                 printf("\n");
                 show_journal_by_unit(i->id, arg_output, 0,
                                      i->inactive_exit_timestamp_monotonic,