[sr-dev] git:master: core: -e - new cli parameter to enable colorful log messages

Elena-Ramona Modroiu ramona at rosdev.ro
Sat Sep 1 16:26:40 CEST 2012


Module: sip-router
Branch: master
Commit: 6bda9c0b7aac195902d2c42123bdde007a9a687f
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=6bda9c0b7aac195902d2c42123bdde007a9a687f

Author: Elena-Ramona Modroiu <ramona at asipto.com>
Committer: Elena-Ramona Modroiu <ramona at asipto.com>
Date:   Sat Sep  1 16:16:21 2012 +0200

core: -e - new cli parameter to enable colorful log messages

- used only when log messages are printed to stderr
- each log level is printed in different color, using term colors (like
  $C(xy) variable)

---

 dprint.c |  203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 dprint.h |   15 +++++
 main.c   |   19 +++++-
 3 files changed, 235 insertions(+), 2 deletions(-)

diff --git a/dprint.c b/dprint.c
index 324d511..90dd110 100644
--- a/dprint.c
+++ b/dprint.c
@@ -140,3 +140,206 @@ void reset_local_debug_level(void)
 {
 	_local_debug_level = UNSET_LOCAL_DEBUG_LEVEL;
 }
+
+typedef struct log_level_color {
+	char f;
+	char b;
+} log_level_color_t;
+
+log_level_color_t _log_level_colors[L_MAX - L_MIN + 1];
+
+void dprint_init_colors(void)
+{
+	int i;
+
+	i = 0;
+
+	memset(_log_level_colors, 0,
+			(L_MAX - L_MIN + 1)*sizeof(log_level_color_t));
+
+	/* L_ALERT */
+	_log_level_colors[i].f = 'R'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_BUG */
+	_log_level_colors[i].f = 'P'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_CRIT2 */
+	_log_level_colors[i].f = 'y'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_CRIT */
+	_log_level_colors[i].f = 'b'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_ERR */
+	_log_level_colors[i].f = 'r'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_WARN */
+	_log_level_colors[i].f = 'p'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_NOTICE */
+	_log_level_colors[i].f = 'g'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_INFO */
+	_log_level_colors[i].f = 'c'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+
+	/* L_DBG */
+	_log_level_colors[i].f = 'x'; /* default */
+	_log_level_colors[i].b = 'x'; /* default */
+	i++;
+}
+
+#define TERM_COLOR_SIZE 16
+
+#define dprint_termc_add(p, end, s) \
+        do{ \
+                if ((p)+(sizeof(s)-1)<=(end)){ \
+                        memcpy((p), s, sizeof(s)-1); \
+                        (p)+=sizeof(s)-1; \
+                }else{ \
+                        /* overflow */ \
+                        LM_ERR("dprint_termc_add overflow\n"); \
+                        goto error; \
+                } \
+        } while(0)
+
+
+void dprint_term_color(char f, char b, str *obuf)
+{
+	static char term_color[TERM_COLOR_SIZE];
+	char* p;
+	char* end;
+
+	p = term_color;
+	end = p + TERM_COLOR_SIZE;
+
+	/* excape sequence */
+	dprint_termc_add(p, end, "\033[");
+
+	if(f!='_')
+	{
+		if (islower((int)f))
+		{
+			/* normal font */
+			dprint_termc_add(p, end, "0;");
+		} else {
+			/* bold font */
+			dprint_termc_add(p, end, "1;");
+			f += 32;
+		}
+	}
+
+	/* foreground */
+	switch(f)
+	{
+		case 'x':
+			dprint_termc_add(p, end, "39;");
+		break;
+		case 's':
+			dprint_termc_add(p, end, "30;");
+		break;
+		case 'r':
+			dprint_termc_add(p, end, "31;");
+		break;
+		case 'g':
+			dprint_termc_add(p, end, "32;");
+		break;
+		case 'y':
+			dprint_termc_add(p, end, "33;");
+		break;
+		case 'b':
+			dprint_termc_add(p, end, "34;");
+		break;
+		case 'p':
+			dprint_termc_add(p, end, "35;");
+		break;
+		case 'c':
+			dprint_termc_add(p, end, "36;");
+		break;
+		case 'w':
+			dprint_termc_add(p, end, "37;");
+		break;
+		default:
+			dprint_termc_add(p, end, "39;");
+	}
+
+	/* background */
+	switch(b)
+	{
+		case 'x':
+			dprint_termc_add(p, end, "49");
+		break;
+		case 's':
+			dprint_termc_add(p, end, "40");
+		break;
+		case 'r':
+			dprint_termc_add(p, end, "41");
+		break;
+		case 'g':
+			dprint_termc_add(p, end, "42");
+		break;
+		case 'y':
+			dprint_termc_add(p, end, "43");
+		break;
+		case 'b':
+			dprint_termc_add(p, end, "44");
+		break;
+		case 'p':
+			dprint_termc_add(p, end, "45");
+		break;
+		case 'c':
+			dprint_termc_add(p, end, "46");
+		break;
+		case 'w':
+			dprint_termc_add(p, end, "47");
+		break;
+		default:
+			dprint_termc_add(p, end, "49");
+	}
+
+	/* end */
+	dprint_termc_add(p, end, "m");
+
+	obuf->s = term_color;
+	obuf->len = p - term_color;
+	return;
+
+error:
+	obuf->s = term_color;
+	term_color[0] = '\0';
+	obuf->len = 0;
+}
+
+void dprint_color(int level)
+{
+	str obuf;
+
+	if(level<L_MIN || level>L_MAX)
+		return;
+	dprint_term_color(_log_level_colors[level - L_MIN].f,
+			_log_level_colors[level - L_MIN].b,
+			&obuf);
+	fprintf(stderr, "%.*s", obuf.len, obuf.s);
+}
+
+void dprint_color_reset(void)
+{
+	str obuf;
+
+	dprint_term_color('x', 'x', &obuf);
+	fprintf(stderr, "%.*s", obuf.len, obuf.s);
+}
diff --git a/dprint.h b/dprint.h
index 6898c9f..04179de 100644
--- a/dprint.h
+++ b/dprint.h
@@ -81,6 +81,7 @@
 /*
  * Log levels
  */
+#define L_MIN		-5
 #define L_ALERT		-5
 #define L_BUG		-4
 #define L_CRIT2		-3  /* like L_CRIT, but adds prefix */
@@ -90,6 +91,7 @@
 #define L_NOTICE 	1
 #define L_INFO   	2
 #define L_DBG    	3
+#define L_MAX    	3
 
 /** @brief This is the facility value used to indicate that the caller of the macro
  * did not override the facility. Value 0 (the defaul) is LOG_KERN on Linux
@@ -109,6 +111,8 @@ extern int my_pid(void);
 /** @brief non-zero if logging to stderr instead to the syslog */
 extern int log_stderr;
 
+extern int log_color;
+
 /** @brief maps log levels to their string name and corresponding syslog level */
 
 struct log_level_info {
@@ -133,6 +137,9 @@ extern volatile int dprint_crit;
 int str2facility(char *s);
 int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 
+void dprint_color(int level);
+void dprint_color_reset(void);
+void dprint_init_colors(void);
 
 /** @brief
  * General logging macros
@@ -175,10 +182,12 @@ int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 					DPRINT_CRIT_ENTER; \
 					if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
 						if (unlikely(log_stderr)) { \
+							if (unlikely(log_color)) dprint_color(level); \
 							fprintf(stderr, "%2d(%d) %s: %s" fmt, \
 									process_no, my_pid(), \
 									LOG_LEVEL2NAME(level), (prefix), \
 									__VA_ARGS__); \
+							if (unlikely(log_color)) dprint_color_reset(); \
 						} else { \
 							syslog(LOG2SYSLOG_LEVEL(level) | \
 								   (((facility) != DEFAULT_FACILITY) ? \
@@ -189,9 +198,11 @@ int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 						} \
 					} else { \
 						if (log_stderr) { \
+							if (unlikely(log_color)) dprint_color(level); \
 							fprintf(stderr, "%2d(%d) %s" fmt, \
 									process_no, my_pid(), \
 									(prefix),  __VA_ARGS__); \
+							if (unlikely(log_color)) dprint_color_reset(); \
 						} else { \
 							if ((level)<L_ALERT) \
 								syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
@@ -237,10 +248,12 @@ int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 					DPRINT_CRIT_ENTER; \
 					if (likely(((level) >= L_ALERT) && ((level) <= L_DBG))){ \
 						if (unlikely(log_stderr)) { \
+							if (unlikely(log_color)) dprint_color(level); \
 							fprintf(stderr, "%2d(%d) %s: %s" fmt, \
 									process_no, my_pid(), \
 									LOG_LEVEL2NAME(level), \
 									(prefix) , ## args);\
+							if (unlikely(log_color)) dprint_color_reset(); \
 						} else { \
 							syslog(LOG2SYSLOG_LEVEL(level) |\
 								   (((facility) != DEFAULT_FACILITY) ? \
@@ -251,9 +264,11 @@ int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 						} \
 					} else { \
 						if (log_stderr) { \
+							if (unlikely(log_color)) dprint_color(level); \
 							fprintf(stderr, "%2d(%d) %s" fmt, \
 										process_no, my_pid(), \
 										(prefix) , ## args); \
+							if (unlikely(log_color)) dprint_color_reset(); \
 						} else { \
 							if ((level)<L_ALERT) \
 								syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
diff --git a/main.c b/main.c
index ca272e1..cf3d665 100644
--- a/main.c
+++ b/main.c
@@ -229,7 +229,8 @@ Options:\n\
     -d           Debugging mode (multiple -d increase the level)\n\
     -D no        1..do not fork (almost) anyway, 2..do not daemonize creator\n\
                   3..daemonize (default)\n\
-    -E           Log to stderr\n"
+    -E           Log to stderr\n\
+    -e           Log messages printed in terminal colors (requires -E)\n"
 #ifdef USE_TCP
 "    -T           Disable tcp\n\
     -N           Number of tcp child processes (default: equal to `-n')\n\
@@ -373,6 +374,7 @@ int sig_flag = 0;              /* last signal received */
 int dont_fork = 0;
 int dont_daemonize = 0;
 int log_stderr = 0;
+int log_color = 0;
 /* set custom app name for syslog printing */
 char *log_name = 0;
 pid_t creator_pid = (pid_t) -1;
@@ -1854,8 +1856,11 @@ int main(int argc, char** argv)
 	dont_fork_cnt=0;
 
 	daemon_status_init();
+
+	dprint_init_colors();
+
 	/* command line options */
-	options=  ":f:cm:M:dVIhEb:l:L:n:vrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:"
+	options=  ":f:cm:M:dVIhEeb:l:L:n:vrRDTN:W:w:t:u:g:P:G:SQ:O:a:A:"
 #ifdef STATS
 		"s:"
 #endif
@@ -1878,6 +1883,9 @@ int main(int argc, char** argv)
 			case 'E':
 					log_stderr=1;
 					break;
+			case 'e':
+					log_color=1;
+					break;
 			case 'M':
 					pkg_mem_size=strtol(optarg, &tmp, 10) * 1024 * 1024;
 					if (tmp &&(*tmp)){
@@ -1972,6 +1980,9 @@ int main(int argc, char** argv)
 			case 'E':
 					/* ignore it, was parsed immediately after startup */
 					break;
+			case 'e':
+					/* ignore it, was parsed immediately after startup */
+					break;
 			case 'O':
 					scr_opt_lev=strtol(optarg, &tmp, 10);
 					if (tmp &&(*tmp)){
@@ -2128,6 +2139,10 @@ try_again:
 					log_stderr=1;	/* use in both getopt switches,
 									   takes priority over config */
 					break;
+			case 'e':
+					log_color=1;	/* use in both getopt switches,
+									   takes priority over config */
+					break;
 			case 'b':
 					maxbuffer=strtol(optarg, &tmp, 10);
 					if (tmp &&(*tmp)){




More information about the sr-dev mailing list