dmesg: more colors, more fun

* colorize subsystem prefix
 * colorize time
 * colorize by keywords (now "segfault" only)

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2013-03-18 12:25:03 +01:00
parent d53f8ecfbf
commit 5aaee63cdf
3 changed files with 101 additions and 21 deletions

View 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"

View 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);
}

View File

@ -57,6 +57,18 @@
/* 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;
mesg = rec->mesg;
mesg_size = rec->mesg_size;
safe_fwrite(rec->mesg, rec->mesg_size, stdout);
/* 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();
if (has_color)
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 }
};