Skip to main content

Coloured Console Debugging

Are you developing a userspace application on Linux?
Do you want it to spew out debug/log messages to a console?
Do you want these messages to be colour coded, categorized by level and module?
Do you want to print the name of the function which generates these messages?
Do you want the ability to turn these messages on and off easily?

If yes, then grab this code:
debug_userspace.h:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
//debug_userspace.h
//Core macros for printing coloured/categorized log messages to console
#ifndef DEBUG_USERSPACE_H
#define DEBUG_USERSPACE_H

/********* ERROR LEVELS
 * Taken from graywizardx's answer at:
 * http://stackoverflow.com/questions/2031163/when-to-use-log-level-warn-vs-error
 *
 * TRACE - Only when I would be "tracing" the code and
 *         trying to find one part of a function specifically
 *
 * DEBUG - Information that is diagnostically helpful to people
 *         more than just developers (IT, sysadmins, etc)
 *
 * INFO  - Generally useful information to log (service start/stop,
 *         configuration assumptions, etc). Info I want to always
 *         have available but usually don't care about under normal
 *         circumstances. This is my out-of-the-box config level.
 *
 * WARNN  - Anything that can potentially cause application oddities,
 *         but for which I am automatically recovering (such as switching
 *         from a primary to backup server, retrying an operation, missing
 *         secondary data, etc)
 *
 * ERROR - Any error which is fatal to the operation but not the service
 *         or application (can't open a required file, missing data, etc).
 *         These errors will force user (administrator, or direct user)
 *         intervention. These are usually reserved (in my apps) for
 *         incorrect connection strings, missing services, etc.
 *
 * FATAL - Any error that is forcing a shutdown of the service or
 *         application to prevent data loss (or further data loss).
 *         I reserve these only for the most heinous errors and situations
 *         where there is guaranteed to have been data corruption or loss.
 */
#define FATAL 1
#define ERROR 2
#define WARNN  3
#define INFO 4
#define DEBUG 5
#define TRACE 6

#define ATTR_FATAL   1
#define FORECOLOR_FATAL  31

#define ATTR_ERROR   1
#define FORECOLOR_ERROR  32

#define ATTR_WARNN   1
#define FORECOLOR_WARNN  33

#define ATTR_INFO   1
#define FORECOLOR_INFO  34

#define ATTR_DEBUG   1
#define FORECOLOR_DEBUG  35

#define ATTR_TRACE   1
#define FORECOLOR_TRACE  36

/*
Userspace programs support color, so why not..
Text attributes
0 All attributes off
1 Bold on
4 Underscore (on monochrome display adapter only)
5 Blink on
7 Reverse video on
8 Concealed on

Foreground colors
30 Black
31 Red
32 Green
33 Yellow
34 Blue
35 Magenta
36 Cyan
37 White

Background colors
40 Black
41 Red
42 Green
43 Yellow
44 Blue
45 Magenta
46 Cyan
47 White
*/


 /********* DEBUG LOG MODULEWISE CONFIGURATION
 */
#include "debug_userspace_config.h"



/********* ACTUAL PRINT MACRO
 */
#define DEBUG_PRINT(MODULE,LEVEL,format, args...) do {         \
  if(DEBUG_ENABLE_##MODULE == 1) {            \
   if(LEVEL <= DEBUG_MINLEVEL_##MODULE) {          \
    printf("%c[%d;%dm" "[%5s:%6s:%s] " "%c[%dm" format  "\n" ,     \
    27, ATTR_##LEVEL, FORECOLOR_##LEVEL, #LEVEL, #MODULE, __func__, 27, 0, ##args );  \
   }                   \
  }                    \
 }while (0)
 
//Following taken from William Whyte's answer at
//http://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format
#define DEBUG_BINARY_PRINTF_SPEC "%d%d%d%d%d%d%d%d"
#define DEBUG_BINARY_PRINTF_ARG(byte) \
  ((byte) & 0x80 ? 1 : 0), \
  ((byte) & 0x40 ? 1 : 0), \
  ((byte) & 0x20 ? 1 : 0), \
  ((byte) & 0x10 ? 1 : 0), \
  ((byte) & 0x08 ? 1 : 0), \
  ((byte) & 0x04 ? 1 : 0), \
  ((byte) & 0x02 ? 1 : 0), \
  ((byte) & 0x01 ? 1 : 0)

#define DEBUG_BINARY_PRINTF_ARG_LO(twobyte) \
   ((twobyte) & 0x0080 ? 1 : 0), \
   ((twobyte) & 0x0040 ? 1 : 0), \
   ((twobyte) & 0x0020 ? 1 : 0), \
   ((twobyte) & 0x0010 ? 1 : 0), \
   ((twobyte) & 0x0008 ? 1 : 0), \
   ((twobyte) & 0x0004 ? 1 : 0), \
   ((twobyte) & 0x0002 ? 1 : 0), \
   ((twobyte) & 0x0001 ? 1 : 0)

#define DEBUG_BINARY_PRINTF_ARG_HI(twobyte) \
   ((twobyte) & 0x8000 ? 1 : 0), \
   ((twobyte) & 0x4000 ? 1 : 0), \
   ((twobyte) & 0x2000 ? 1 : 0), \
   ((twobyte) & 0x1000 ? 1 : 0), \
   ((twobyte) & 0x0800 ? 1 : 0), \
   ((twobyte) & 0x0400 ? 1 : 0), \
   ((twobyte) & 0x0200 ? 1 : 0), \
   ((twobyte) & 0x0100 ? 1 : 0)

#endif //DEBUG_USERSPACE_H

debug_userpsace_config.h:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
//debug_userspace_config.h
//Core macros for printing coloured/categorized log messages to console
//You can control the visibility of message module wise and level wise at compile time.
//To add a new module, just make a new entry in this file
//Messages classified above and including the minimum level set by DEBUG_MINLEVEL_XXX will be displayed

#ifndef DEBUG_USERSPACE_CONFIG_H_
#define DEBUG_USERSPACE_CONFIG_H_

/********* CONFIGURATION FOR INDIVIDUAL MODULES
 * Enable Debug Messages = 1
 * Disable Debug Messages = 0
 */
#define DEBUG_ENABLE_MAIN 1
#define DEBUG_MINLEVEL_MAIN TRACE

#define DEBUG_ENABLE_TEST 1
#define DEBUG_MINLEVEL_TEST WARNN

#endif //DEBUG_USERSPACE_CONFIG_H_

main.c (to demonstrate the use of the macros):
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//main.c
//Demonstrating the use of coloured and categorized macros for printing log messages
#include <stdio.h>
#include <stdlib.h>
#include "debug_userspace.h"

int main(void) {
 short int abc = 1000;
 DEBUG_PRINT(MAIN,TRACE,"Trace level message");
 DEBUG_PRINT(MAIN,DEBUG,"Debug level message");
 DEBUG_PRINT(MAIN,INFO,"Informative level message");
 DEBUG_PRINT(TEST,WARNN,"Warning level message");
 DEBUG_PRINT(TEST,ERROR,"Error level message");
 DEBUG_PRINT(TEST,FATAL,"Fatal level message");
 
 DEBUG_PRINT(TEST,TRACE,"This message won't be printed. Message level is less than configured level.");
 
 DEBUG_PRINT(TEST,FATAL,"170 in binary is 0b" DEBUG_BINARY_PRINTF_SPEC, DEBUG_BINARY_PRINTF_ARG(170));
 DEBUG_PRINT(TEST,FATAL,"%d in binary is 0b" DEBUG_BINARY_PRINTF_SPEC DEBUG_BINARY_PRINTF_SPEC, \
  abc, DEBUG_BINARY_PRINTF_ARG_HI(abc), DEBUG_BINARY_PRINTF_ARG_LO(abc));
 
 exit(EXIT_SUCCESS);
}

Here is what the output of main.c looks like:

Output of main.c


Note: This works over console accessed over serial port of any embedded ARM/Linux system too. Just make sure to use PuTTY to access the console:

PuTTY displays the colour coded log messages faithfully
Source files are here

Comments

  1. Fore more colors, try

    $ sudo apt-get install colortest

    $ /usr/bin/colortest-8
    $ /usr/bin/colortest-16
    $ /usr/bin/colortest-16b
    $ /usr/bin/colortest-256

    ReplyDelete

Post a Comment