dmesg colorized output
Subsystems (2)
PATCH 1/1 dmesg colorized output
Hi, this patch should implement the dmesg entry in your TODO list. I've also created a tiny colors module, which should be enough for simple output coloring for other programs in the future. Cheers,
Ondrej.
Quoted 1 line
From
1a89c8497525030c8710c3936aa8d558976f0502Mon Sep 17 00:00:00 2001
From: Ondrej Oprala <[email protected]>
Date: Tue, 9 Oct 2012 12:32:55 +0200
Subject: [PATCH] dmesg: Add a --color option to colorize error and panic
messages
--- include/colors.h | 19 +++++++++++++++++++ lib/Makemodule.am | 1 + lib/colors.c | 20 ++++++++++++++++++++ sys-utils/dmesg.c | 28 ++++++++++++++++++++++++---- 4 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 include/colors.h create mode 100644 lib/colors.c
include/colors.h new file +19 -0
@@ -0,0 +1,19 @@ +/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include <stdio.h> +#include <unistd.h> +#define CLR_RST "\033[0m" + +/* +* Set output colors according to CLR_SCHEME, which should +* be in ANSI color code format +*/ +extern void set_clr (const char *clr_scheme,FILE *out); + +/* Reset to default */ +extern void rst_clr (FILE *out);
lib/Makemodule.am +1 -0
@@ -5,6 +5,7 @@ libcommon_la_SOURCES = \ lib/at.c \ lib/blkdev.c \ lib/canonicalize.c \ + lib/colors.c \ lib/cpuset.c \ lib/crc32.c \ lib/env.c \
lib/colors.c new file +20 -0
@@ -0,0 +1,20 @@ +/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include "colors.h" + +void set_clr (const char *clr_scheme,FILE *out) +{ +if (isatty (fileno (out))) +fprintf (out, clr_scheme); +} + +void rst_clr (FILE *out) +{ +if (isatty (fileno (out))) +fprintf (out,CLR_RST ); +}
sys-utils/dmesg.c +24 -4
@@ -23,6 +23,7 @@#include <fcntl.h> #include "c.h" +#include "colors.h" #include "nls.h" #include "strutils.h" #include "xalloc.h"
@@ -33,6 +34,11 @@#include "optutils.h" #include "mangle.h" +#define K_PANIC 1 +#define K_ERR 3 +#define CLR_PANIC "\033[31m" //Red +#define CLR_ERR "\033[1;31m" //Bright Red +/* Close the log. Currently a NOP. */ #define SYSLOG_ACTION_CLOSE 0/* Open the log. Currently a NOP. */
@@ -147,7 +153,8 @@ struct dmesg_control { notime:1, /* don't print timestamp */ delta:1, /* show time deltas */ reltime:1, /* show human readable relative times */ - ctime:1; /* show human readable time */ + ctime:1, /* show human readable time */ + color:1; /* colorize error and panic messages */ };struct dmesg_record {
@@ -193,6 +200,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)" -f, --facility <list> restrict output to defined facilities\n" " -h, --help display this help and exit\n" " -k, --kernel display kernel messages\n" +" -L, --color colorize error and panic messages\n" " -l, --level <list> restrict output to defined levels\n" " -n, --console-level <level> set level of messages printed to console\n" " -r, --raw print the raw message buffer\n"
@@ -839,8 +847,16 @@ static void print_record(struct dmesg_control *ctl,printf ("[%5d.%06d] " , (int ) rec->tv.tv_sec, (int ) rec->tv.tv_usec); mesg: +//Change the output color for panic and error messages +if (ctl->color) +set_clr (rec->level ==K_PANIC ?CLR_PANIC : + rec->level ==K_ERR ?CLR_ERR :CLR_RST , stdout); +safe_fwrite (rec->mesg, rec->mesg_size, stdout); +if (ctl->color) +rst_clr (stdout); +if (*(rec->mesg + rec->mesg_size -1 ) !='\n' )putchar ('\n' ); }
@@ -1046,6 +1062,7 @@ int main(int argc, char *argv[])static const struct option longopts[] = { {"buffer-size" , required_argument,NULL ,'s' }, {"clear" , no_argument,NULL ,'C' }, + {"color" , no_argument,NULL ,'L' }, {"console-level" , required_argument,NULL ,'n' }, {"console-off" , no_argument,NULL ,'D' }, {"console-on" , no_argument,NULL ,'E' },
@@ -1080,7 +1097,7 @@ int main(int argc, char *argv[])textdomain (PACKAGE );atexit (close_stdout); -while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkl:n:rSs:TtuVwx" , +while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkLl:n:rSs:TtuVwx" , longopts,NULL )) !=-1 ) {err_exclusive_options (c, longopts, excl, excl_st);
@@ -1123,6 +1140,9 @@ int main(int argc, char *argv[]) ctl.fltr_fac =1 ;setbit (ctl.facilities,FAC_BASE (LOG_KERN ));break ; +case 'L' : + ctl.color =1 ; +break ;case 'l' : ctl.fltr_lev=1 ; if (string_to_bitarray(optarg,
@@ -1180,9 +1200,9 @@ int main(int argc, char *argv[])usage (stderr);if (ctl.raw && (ctl.fltr_lev || ctl.fltr_fac || ctl.delta || - ctl.notime || ctl.ctime || ctl.decode)) + ctl.notime || ctl.ctime || ctl.decode || ctl.color))errx (EXIT_FAILURE ,_ ("--raw can't be used together with level, " -"facility, decode, delta, ctime or notime options" )); +"facility, decode, delta, ctime, notime or color options" ));if (ctl.notime && (ctl.ctime || ctl.reltime))errx (EXIT_FAILURE ,_ ("--notime can't be used together with --ctime or --reltime" ));
Signature · 1 line
1.7.11.4
Karel Zak
maintainerinclude/colors.h
Quoted 5 lines · Ondrej Oprala
new file mode 100644
index 0000000..90b62a7include/colors.h new file +0
-0@@ -0,0 +1,19 @@
Please, see another files in include/.
#ifndef UTIL_LINUX_COLOR_H
#define UTIL_LINUX_COLOR_H
include/colors.h line 10
Quoted 10 lines
include/colors.h new file +10
-0+/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include <stdio.h> +#include <unistd.h> +#define CLR_RST "\033[0m"
#define UL_COLOR_RESET
to keep it readable. It would be also nice to have macros for individual colors (UL_COLOR_{RED,YELLOW,BLUE,...} and extra modes like bold.
(It's also possible to set background colors, but I guess that foreground colors are enough for our utils.)
lib/colors.c line 10
Quoted 13 lines
lib/colors.c new file +10
-0@@ -0,0 +1,20 @@ +/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include "colors.h" + +void set_clr (const char *clr_scheme,FILE *out)
color_enable()
Is it necessary to care about "out"? Maybe we can assume that the output is stdout.
lib/colors.c line 14
Quoted 4 lines
lib/colors.c new file +4
-0+{ +if (isatty (fileno (out))) +fprintf (out, clr_scheme); +}
if I good remember than isatty() is internally implemented by any ioctl(). It would be probably better to have something like:
int colors_init();
where we check all necessary terminal features and initialize a global variable, so in color_enable/disable() we will check the variable only.
lib/colors.c line 16
Quoted 1 line
lib/colors.c new file +1
-0+void rst_clr (FILE *out)
color_disable()
Maybe for the functions names we should also use ul_ prefix to avoid collisions (for example ncurses library also uses pretty generic names for color functions).
lib/colors.c line 20
Quoted 4 lines
lib/colors.c new file +4
-0+{ +if (isatty (fileno (out))) +fprintf (out,CLR_RST ); +}
Please, use fputs() rather than fprintf().
Quoted 13 lines
sys-utils/dmesg.c +1
-0@@ -23,6 +23,7 @@#include <fcntl.h> #include "c.h" +#include "colors.h" #include "nls.h" #include "strutils.h" #include "xalloc.h"
sys-utils/dmesg.c line 38
Quoted 5 lines
sys-utils/dmesg.c +2
-0@@ -33,6 +34,11 @@#include "optutils.h" #include "mangle.h" +#define K_PANIC 1 +#define K_ERR 3
really no, already defined by LOG_* macros in <sys/syslog.h>, see also level_names[] array in dmesg.c.
sys-utils/dmesg.c line 40
Quoted 2 lines
sys-utils/dmesg.c +2
-0+#define CLR_PANIC "\033[31m" //Red +#define CLR_ERR "\033[1;31m" //Bright Red
#define DMESG_COLOR_ALERT UL_COLOR_RED
#define DMESG_COLOR_ERR UL_COLOR_BRIGHT_RED
Quoted 22 lines
sys-utils/dmesg.c +3
-1/* Close the log. Currently a NOP. */ #define SYSLOG_ACTION_CLOSE 0/* Open the log. Currently a NOP. */ @@ -147,7 +153,8 @@ struct dmesg_control { notime:1, /* don't print timestamp */ delta:1, /* show time deltas */ reltime:1, /* show human readable relative times */ - ctime:1; /* show human readable time */ + ctime:1, /* show human readable time */ + color:1; /* colorize error and panic messages */ };struct dmesg_record {@@ -193,6 +200,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)" -f, --facility <list> restrict output to defined facilities\n" " -h, --help display this help and exit\n" " -k, --kernel display kernel messages\n" +" -L, --color colorize error and panic messages\n" " -l, --level <list> restrict output to defined levels\n" " -n, --console-level <level> set level of messages printed to console\n" " -r, --raw print the raw message buffer\n"
sys-utils/dmesg.c static void print_record(struct dmesg_control *ctl, · line 853
Quoted 7 lines
sys-utils/dmesg.c +4
-0@@ -839,8 +847,16 @@ static void print_record(struct dmesg_control *ctl,printf ("[%5d.%06d] " , (int ) rec->tv.tv_sec, (int ) rec->tv.tv_usec); mesg: +//Change the output color for panic and error messages +if (ctl->color) +set_clr (rec->level ==K_PANIC ?CLR_PANIC : + rec->level ==K_ERR ?CLR_ERR :CLR_RST , stdout);
keep it elegant:
if (ctl->color)
set_level_color(rec->level);:-)
Quoted 36 lines
sys-utils/dmesg.c +8
-1safe_fwrite (rec->mesg, rec->mesg_size, stdout); +if (ctl->color) +rst_clr (stdout); +if (*(rec->mesg + rec->mesg_size -1 ) !='\n' )putchar ('\n' ); }@@ -1046,6 +1062,7 @@ int main(int argc, char *argv[])static const struct option longopts[] = { {"buffer-size" , required_argument,NULL ,'s' }, {"clear" , no_argument,NULL ,'C' }, + {"color" , no_argument,NULL ,'L' }, {"console-level" , required_argument,NULL ,'n' }, {"console-off" , no_argument,NULL ,'D' }, {"console-on" , no_argument,NULL ,'E' },@@ -1080,7 +1097,7 @@ int main(int argc, char *argv[])textdomain (PACKAGE );atexit (close_stdout); -while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkl:n:rSs:TtuVwx" , +while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkLl:n:rSs:TtuVwx" , longopts,NULL )) !=-1 ) {err_exclusive_options (c, longopts, excl, excl_st);@@ -1123,6 +1140,9 @@ int main(int argc, char *argv[]) ctl.fltr_fac =1 ;setbit (ctl.facilities,FAC_BASE (LOG_KERN ));break ; +case 'L' : + ctl.color =1 ; +break ;case 'l' : ctl.fltr_lev=1 ; if (string_to_bitarray(optarg,
sys-utils/dmesg.c int main(int argc, char *argv[]) · line 1205
Quoted 8 lines
sys-utils/dmesg.c +2
-2@@ -1180,9 +1200,9 @@ int main(int argc, char *argv[])usage (stderr);if (ctl.raw && (ctl.fltr_lev || ctl.fltr_fac || ctl.delta || - ctl.notime || ctl.ctime || ctl.decode)) + ctl.notime || ctl.ctime || ctl.decode || ctl.color))errx (EXIT_FAILURE ,_ ("--raw can't be used together with level, " -"facility, decode, delta, ctime or notime options" )); +"facility, decode, delta, ctime, notime or color options" ));
if (ctl.color && ul_color_init() != 0)
ctl.color = 0;Thanks!
Karel
Signature · 2 lines
Karel Zak <[email protected]> http://karelzak.blogspot.com
Quoted 2 lines · Karel Zak
Quoted 1 line · Ondrej Oprala
new file mode 100644
Hehe I actually started doing this last night.
I'm wondering if we actually need a new lib file for colors. I mean AFAICT, dmesg is the only place we want to use it and I don't see that changing any time soon - Unix hackers don't like colors, we live oh so boring lives :)
Quoted 94 lines
include/colors.h
Quoted 4 lines
index 0000000..90b62a7
include/colors.h new file +0
-0@@ -0,0 +1,19 @@Please, see another files in
include/.#ifndef
UTIL_LINUX_COLOR_H
#defineUTIL_LINUX_COLOR_Hinclude/colors.h line 10
Quoted 10 lines
include/colors.h new file +10
-0+/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include <stdio.h> +#include <unistd.h> +#define CLR_RST "\033[0m"#define UL_COLOR_RESETto keep it readable. It would be also nice to have macros for individual colors (UL_COLOR_{RED,YELLOW,BLUE,...} and extra modes like bold.
(It's also possible to set background colors, but I guess that foreground colors are enough for our utils.)
lib/colors.c line 10
Quoted 13 lines
lib/colors.c new file +10
-0@@ -0,0 +1,20 @@ +/* +* Copyright (C) 2012 Ondrej Oprala <[email protected]> +* +* This file may be distributed under the terms of the +* GNU Lesser General Public License. +*/ + +#include "colors.h" + +void set_clr (const char *clr_scheme,FILE *out)
color_enable()Is it necessary to care about "out"? Maybe we can assume that the output is stdout.
lib/colors.c line 14
Quoted 4 lines
lib/colors.c new file +4
-0+{ +if (isatty (fileno (out))) +fprintf (out, clr_scheme); +}if I good remember than
isatty()is internally implemented by anyioctl(). It would be probably better to have something like:int colors_init();where we check all necessary terminal features and initialize a global variable, so in color_enable/disable() we will check the variable only.
lib/colors.c line 16
Quoted 1 line
lib/colors.c new file +1
-0+void rst_clr (FILE *out)
color_disable()Maybe for the functions names we should also use
ul_prefix to avoid collisions (for example ncurses library also uses pretty generic names for color functions).lib/colors.c line 20
Quoted 4 lines
lib/colors.c new file +4
-0+{ +if (isatty (fileno (out))) +fprintf (out,CLR_RST ); +}Please, use
fputs()rather thanfprintf().Quoted 16 lines
sys-utils/dmesg.c +1
-0@@ -23,6 +23,7 @@#include <fcntl.h> #include "c.h" +#include "colors.h" #include "nls.h" #include "strutils.h" #include "xalloc.h" @@ -33,6 +34,11 @@#include "optutils.h" #include "mangle.h"
Quoted 8 lines
sys-utils/dmesg.c line 38
Quoted 2 lines
sys-utils/dmesg.c +2
-0+#define K_PANIC 1 +#define K_ERR 3really no, already defined by LOG_* macros in <
sys/syslog.h>, see also level_names[] array indmesg.c.sys-utils/dmesg.c line 40
Quoted 2 lines
sys-utils/dmesg.c +2
-0+#define CLR_PANIC "\033[31m" //Red +#define CLR_ERR "\033[1;31m" //Bright Red
how about using /* ... */
Quoted 94 lines
#define
DMESG_COLOR_ALERTUL_COLOR_RED
#defineDMESG_COLOR_ERRUL_COLOR_BRIGHT_REDQuoted 22 lines
sys-utils/dmesg.c +3
-1/* Close the log. Currently a NOP. */ #define SYSLOG_ACTION_CLOSE 0/* Open the log. Currently a NOP. */ @@ -147,7 +153,8 @@ struct dmesg_control { notime:1, /* don't print timestamp */ delta:1, /* show time deltas */ reltime:1, /* show human readable relative times */ - ctime:1; /* show human readable time */ + ctime:1, /* show human readable time */ + color:1; /* colorize error and panic messages */ };struct dmesg_record {@@ -193,6 +200,7 @@ static void __attribute__((__noreturn__)) usage(FILE *out)" -f, --facility <list> restrict output to defined facilities\n" " -h, --help display this help and exit\n" " -k, --kernel display kernel messages\n" +" -L, --color colorize error and panic messages\n" " -l, --level <list> restrict output to defined levels\n" " -n, --console-level <level> set level of messages printed to console\n" " -r, --raw print the raw message buffer\n" sys-utils/dmesg.c static void print_record(struct dmesg_control *ctl, · line 853
Quoted 7 lines
sys-utils/dmesg.c +4
-0@@ -839,8 +847,16 @@ static void print_record(struct dmesg_control *ctl,printf ("[%5d.%06d] " , (int ) rec->tv.tv_sec, (int ) rec->tv.tv_usec); mesg: +//Change the output color for panic and error messages +if (ctl->color) +set_clr (rec->level ==K_PANIC ?CLR_PANIC : + rec->level ==K_ERR ?CLR_ERR :CLR_RST , stdout);keep it elegant:
if (ctl->color) set_level_color(rec->level);:-)
Quoted 36 lines
sys-utils/dmesg.c +8
-1safe_fwrite (rec->mesg, rec->mesg_size, stdout); +if (ctl->color) +rst_clr (stdout); +if (*(rec->mesg + rec->mesg_size -1 ) !='\n' )putchar ('\n' ); }@@ -1046,6 +1062,7 @@ int main(int argc, char *argv[])static const struct option longopts[] = { {"buffer-size" , required_argument,NULL ,'s' }, {"clear" , no_argument,NULL ,'C' }, + {"color" , no_argument,NULL ,'L' }, {"console-level" , required_argument,NULL ,'n' }, {"console-off" , no_argument,NULL ,'D' }, {"console-on" , no_argument,NULL ,'E' },@@ -1080,7 +1097,7 @@ int main(int argc, char *argv[])textdomain (PACKAGE );atexit (close_stdout); -while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkl:n:rSs:TtuVwx" , +while ((c =getopt_long (argc, argv,"CcDdEeF:f:hkLl:n:rSs:TtuVwx" , longopts,NULL )) !=-1 ) {err_exclusive_options (c, longopts, excl, excl_st);@@ -1123,6 +1140,9 @@ int main(int argc, char *argv[]) ctl.fltr_fac =1 ;setbit (ctl.facilities,FAC_BASE (LOG_KERN ));break ; +case 'L' : + ctl.color =1 ; +break ;case 'l' : ctl.fltr_lev=1 ; if (string_to_bitarray(optarg,sys-utils/dmesg.c int main(int argc, char *argv[]) · line 1205
Quoted 8 lines
sys-utils/dmesg.c +2
-2@@ -1180,9 +1200,9 @@ int main(int argc, char *argv[])usage (stderr);if (ctl.raw && (ctl.fltr_lev || ctl.fltr_fac || ctl.delta || - ctl.notime || ctl.ctime || ctl.decode)) + ctl.notime || ctl.ctime || ctl.decode || ctl.color))errx (EXIT_FAILURE ,_ ("--raw can't be used together with level, " -"facility, decode, delta, ctime or notime options" )); +"facility, decode, delta, ctime, notime or color options" ));if (ctl.color && ul_color_init() != 0) ctl.color = 0;Thanks!
Karel
Karel Zak
maintainerQuoted 8 lines · Davidlohr Bueso
Quoted 2 lines · Karel Zak
Quoted 1 line · Ondrej Oprala
new file mode 100644
Hehe I actually started doing this last night.
I'm wondering if we actually need a new lib file for colors. I mean AFAICT, dmesg is the only place we want to use it and I don't see that
What about fdisk where we have many dialogs, warnings, hints? :-) It's not about colors only, but also about bold, etc.
The another possibility is namei(1) where we can provide output compatible with ls(1), or cal(1), etc.
Quoted 2 lines
changing any time soon - Unix hackers don't like colors, we live oh so boring lives :)
All this should be optional. I guess than many people use aliases with colors
$ alias | grep color alias egrep='egrep --color=tty' alias fgrep='fgrep --color=tty' alias grep='grep --color=tty' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' alias ls='ls --color=auto'
Karel
Signature · 2 lines
Karel Zak <[email protected]> http://karelzak.blogspot.com
Quoted 22 lines · Karel Zak
Quoted 8 lines · Davidlohr Bueso
Quoted 2 lines · Karel Zak
Quoted 1 line · Ondrej Oprala
new file mode 100644
Hehe I actually started doing this last night.
I'm wondering if we actually need a new lib file for colors. I mean AFAICT, dmesg is the only place we want to use it and I don't see that
What about fdisk where we have many dialogs, warnings, hints? :-) It's not about colors only, but also about bold, etc.
The another possibility is namei(1) where we can provide output compatible with ls(1), or cal(1), etc.
Quoted 2 lines
changing any time soon - Unix hackers don't like colors, we live oh so boring lives :)
All this should be optional. I guess than many people use aliases with colors
Quoted 7 lines
$ alias | grep color alias egrep='egrep --color=tty' alias fgrep='fgrep --color=tty' alias grep='grep --color=tty' alias l.='ls -d .* --color=auto' alias ll='ls -l --color=auto' alias ls='ls --color=auto'
I totally agree. Colored output from various tools could make it easier to work with, but it has to be optional.
My 2c.
Petr
Signature · 2 lines
Petr Uzel IRC: ptr_uzl @ freenode