]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
dmesg: more colors, more fun
authorKarel Zak <kzak@redhat.com>
Mon, 18 Mar 2013 11:25:03 +0000 (12:25 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 18 Mar 2013 11:28:32 +0000 (12:28 +0100)
 * colorize subsystem prefix
 * colorize time
 * colorize by keywords (now "segfault" only)

Signed-off-by: Karel Zak <kzak@redhat.com>
include/colors.h
lib/colors.c
sys-utils/dmesg.c

index 0eb19464f520a8b881949ad9b783be53fdf0d732..dd77bf6df256eba1f95ad9b3e86b6f4739f58dd3 100644 (file)
@@ -21,7 +21,7 @@
 #define UL_COLOR_BLACK         "\033[30m"
 #define UL_COLOR_RED           "\033[31m"
 #define UL_COLOR_GREEN         "\033[32m"
-#define UL_COLOR_YELLOW                "\033[33m"
+#define UL_COLOR_BROWN         "\033[33m"      /* well, brown */
 #define UL_COLOR_BLUE          "\033[34m"
 #define UL_COLOR_MAGENTA       "\033[35m"
 #define UL_COLOR_CYAN          "\033[36m"
index bb9c057e10d8867d80411fe9970c027cf208cb51..6af038b318e32cdb7ec3ce9d8ec7f56279f59591 100644 (file)
@@ -17,7 +17,7 @@ int colors_init(void)
 
 void color_enable(const char *color_scheme)
 {
-       if (ul_color_term_ok)
+       if (ul_color_term_ok && color_scheme)
                fputs(color_scheme, stdout);
 }
 
index 48c121fe89d191601b75685faa9301b79acbae53..685d415aa86443f03deae75bd8f4bafdf9eff331 100644 (file)
 /* Return size of the log buffer */
 #define SYSLOG_ACTION_SIZE_BUFFER   10
 
+/*
+ * Colors
+ */
+#define DMESG_COLOR_SUBSYS     UL_COLOR_BROWN
+#define DMESG_COLOR_TIME       UL_COLOR_GREEN
+#define DMESG_COLOR_RELTIME    UL_COLOR_BOLD_GREEN
+#define DMESG_COLOR_ALERT      UL_COLOR_REVERSE UL_COLOR_RED
+#define DMESG_COLOR_CRIT       UL_COLOR_BOLD_RED
+#define DMESG_COLOR_ERR                UL_COLOR_RED
+#define DMESG_COLOR_WARN       UL_COLOR_BOLD
+#define DMESG_COLOR_SEGFAULT   UL_COLOR_HALFBRIGHT UL_COLOR_RED
+
 /*
  * Priority and facility names
  */
@@ -175,22 +187,33 @@ struct dmesg_record {
 
 static int read_kmsg(struct dmesg_control *ctl);
 
-static int set_level_color(int log_level)
+static int set_level_color(int log_level, const char *mesg, size_t mesgsz)
 {
        switch (log_level) {
        case LOG_ALERT:
-               color_enable(UL_COLOR_BOLD_RED);
+               color_enable(DMESG_COLOR_ALERT);
                return 0;
        case LOG_CRIT:
-               color_enable(UL_COLOR_RED);
+               color_enable(DMESG_COLOR_CRIT);
                return 0;
        case LOG_ERR:
-               color_enable(UL_COLOR_BOLD);
+               color_enable(DMESG_COLOR_ERR);
+               return 0;
+       case LOG_WARNING:
+               color_enable(DMESG_COLOR_WARN);
                return 0;
        default:
                break;
        }
 
+       /* well, sometimes the messges contains important keywords, but in
+        * non-warning/error messages
+        */
+       if (memmem(mesg, mesgsz, "segfault at", 11)) {
+               color_enable(DMESG_COLOR_SEGFAULT);
+               return 0;
+       }
+
        return 1;
 }
 
@@ -768,11 +791,32 @@ static double record_count_delta(struct dmesg_control *ctl,
        return delta;
 }
 
+static const char *get_subsys_delimiter(const char *mesg, size_t mesg_size)
+{
+       const char *p = mesg;
+       size_t sz = mesg_size;
+
+       while (sz > 0) {
+               const char *d = strnchr(p, sz, ':');
+               if (!d)
+                       return NULL;
+               sz -= d - p;
+               if (sz) {
+                       if (isblank(*(d + 1)))
+                               return d;
+                       p = d + 1;
+               }
+       }
+       return NULL;
+}
+
 static void print_record(struct dmesg_control *ctl,
                         struct dmesg_record *rec)
 {
        char buf[256];
        int has_color = 0;
+       const char *mesg;
+       size_t mesg_size;
 
        if (!accept_record(ctl, rec))
                return;
@@ -808,6 +852,8 @@ static void print_record(struct dmesg_control *ctl,
         * [sec.usec <delta>] or [ctime <delta>]
         */
        if (ctl->delta) {
+               if (ctl->color)
+                       color_enable(DMESG_COLOR_TIME);
                if (ctl->ctime)
                        printf("[%s ", record_ctime(ctl, rec, buf, sizeof(buf)));
                else if (ctl->notime)
@@ -816,12 +862,19 @@ static void print_record(struct dmesg_control *ctl,
                        printf("[%5d.%06d ", (int) rec->tv.tv_sec,
                                             (int) rec->tv.tv_usec);
                printf("<%12.06f>] ", record_count_delta(ctl, rec));
+               if (ctl->color)
+                       color_disable();
 
        /*
         * [ctime]
         */
-       } else if (ctl->ctime)
+       } else if (ctl->ctime) {
+               if (ctl->color)
+                       color_enable(DMESG_COLOR_TIME);
                printf("[%s] ", record_ctime(ctl, rec, buf, sizeof(buf)));
+               if (ctl->color)
+                       color_disable();
+       }
 
        /*
         * [reltime]
@@ -835,13 +888,20 @@ static void print_record(struct dmesg_control *ctl,
 
                if (cur.tm_min  != ctl->lasttm.tm_min ||
                    cur.tm_hour != ctl->lasttm.tm_hour ||
-                   cur.tm_yday != ctl->lasttm.tm_yday)
+                   cur.tm_yday != ctl->lasttm.tm_yday) {
+                       if (ctl->color)
+                               color_enable(DMESG_COLOR_RELTIME);
                        printf("[%s] ", short_ctime(&cur, buf, sizeof(buf)));
-               else if (delta < 10)
-                       printf("[  %+8.06f] ", delta);
-               else
-                       printf("[ %+9.06f] ", delta);
-
+               } else {
+                       if (ctl->color)
+                               color_enable(DMESG_COLOR_TIME);
+                       if (delta < 10)
+                               printf("[  %+8.06f] ", delta);
+                       else
+                               printf("[ %+9.06f] ", delta);
+               }
+               if (ctl->color)
+                       color_disable();
                ctl->lasttm = cur;
        }
 
@@ -854,20 +914,39 @@ static void print_record(struct dmesg_control *ctl,
         * the [sec.usec] string.
         */
        if (ctl->method == DMESG_METHOD_KMSG &&
-           !ctl->notime && !ctl->delta && !ctl->ctime && !ctl->reltime)
+           !ctl->notime && !ctl->delta && !ctl->ctime && !ctl->reltime) {
+               if (ctl->color)
+                       color_enable(DMESG_COLOR_TIME);
                printf("[%5d.%06d] ", (int) rec->tv.tv_sec, (int) rec->tv.tv_usec);
+               if (ctl->color)
+                       color_disable();
+       }
 
 mesg:
-       /* Change the output color for panic and error messages */
-       if (ctl->color)
-               has_color = set_level_color(rec->level) == 0;
-
-       safe_fwrite(rec->mesg, rec->mesg_size, stdout);
-
-       if (has_color)
-               color_disable();
+       mesg = rec->mesg;
+       mesg_size = rec->mesg_size;
+
+       /* Colorize output */
+       if (ctl->color) {
+               /* subsystem prefix */
+               const char *subsys = get_subsys_delimiter(mesg, mesg_size);
+               if (subsys) {
+                       color_enable(DMESG_COLOR_SUBSYS);
+                       safe_fwrite(mesg, subsys - mesg, stdout);
+                       color_disable();
+
+                       mesg_size -= subsys - mesg;
+                       mesg = subsys;
+               }
+               /* error, alert .. etc. colors */
+               has_color = set_level_color(rec->level, mesg, mesg_size) == 0;
+               safe_fwrite(mesg, mesg_size, stdout);
+               if (has_color)
+                       color_disable();
+       } else
+               safe_fwrite(mesg, mesg_size, stdout);
 
-       if (*(rec->mesg + rec->mesg_size - 1) != '\n')
+       if (*(mesg + mesg_size - 1) != '\n')
                putchar('\n');
 }
 
@@ -1098,6 +1177,7 @@ int main(int argc, char *argv[])
 
        static const ul_excl_t excl[] = {       /* rows and cols in in ASCII order */
                { 'C','D','E','c','n' },        /* clear,off,on,read-clear,level*/
+               { 'L','r' },                    /* color, raw */
                { 'S','w' },                    /* syslog,follow */
                { 0 }
        };