From 8656f9c3676f6be0ad9c1f2603389ffab2dca8d2 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Sun, 18 Sep 2011 14:38:46 +0000 Subject: Implemented re #1372: New log features: indentation and thread switching indication git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3752 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib/include/pj/config.h | 27 +++++++++++ pjlib/include/pj/log.h | 23 +++++++++- pjlib/src/pj/log.c | 111 ++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 152 insertions(+), 9 deletions(-) (limited to 'pjlib') diff --git a/pjlib/include/pj/config.h b/pjlib/include/pj/config.h index 293e3f0f..cab05770 100644 --- a/pjlib/include/pj/config.h +++ b/pjlib/include/pj/config.h @@ -408,6 +408,33 @@ # define PJ_LOG_USE_STACK_BUFFER 1 #endif +/** + * Enable log indentation feature. + * + * Default: 1 + */ +#ifndef PJ_LOG_ENABLE_INDENT +# define PJ_LOG_ENABLE_INDENT 1 +#endif + +/** + * Number of PJ_LOG_INDENT_CHAR to put every time pj_log_push_indent() + * is called. + * + * Default: 1 + */ +#ifndef PJ_LOG_INDENT_SIZE +# define PJ_LOG_INDENT_SIZE 1 +#endif + +/** + * Log indentation character. + * + * Default: space + */ +#ifndef PJ_LOG_INDENT_CHAR +# define PJ_LOG_INDENT_CHAR '.' +#endif /** * Colorfull terminal (for logging etc). diff --git a/pjlib/include/pj/log.h b/pjlib/include/pj/log.h index 83522d07..103469f9 100644 --- a/pjlib/include/pj/log.h +++ b/pjlib/include/pj/log.h @@ -81,7 +81,9 @@ enum pj_log_decoration PJ_LOG_HAS_SPACE = 512, /**< Include two spaces before log [yes] */ PJ_LOG_HAS_COLOR = 1024, /**< Colorize logs [yes on win32] */ PJ_LOG_HAS_LEVEL_TEXT = 2048, /**< Include level text string [no] */ - PJ_LOG_HAS_THREAD_ID = 4096 /**< Include thread identification [no] */ + PJ_LOG_HAS_THREAD_ID = 4096, /**< Include thread identification [no] */ + PJ_LOG_HAS_THREAD_SWC = 8192, /**< Add mark when thread has switched [yes]*/ + PJ_LOG_HAS_INDENT =16384 /**< Indentation. Say yes! [yes] */ }; /** @@ -203,6 +205,25 @@ PJ_DECL(void) pj_log_set_decor(unsigned decor); */ PJ_DECL(unsigned) pj_log_get_decor(void); +/** + * Add indentation to log message. Indentation will add PJ_LOG_INDENT_CHAR + * before the message, and is useful to show the depth of function calls. + * + * @param indent The indentation to add or substract. Positive value + * adds current indent, negative value subtracts current + * indent. + */ +PJ_DECL(void) pj_log_add_indent(int indent); + +/** + * Push indentation to the right by default value (PJ_LOG_INDENT). + */ +PJ_DECL(void) pj_log_push_indent(void); + +/** + * Pop indentation (to the left) by default value (PJ_LOG_INDENT). + */ +PJ_DECL(void) pj_log_pop_indent(void); /** * Set color of log messages. diff --git a/pjlib/src/pj/log.c b/pjlib/src/pj/log.c index 0438007e..86bfefdd 100644 --- a/pjlib/src/pj/log.c +++ b/pjlib/src/pj/log.c @@ -31,14 +31,24 @@ PJ_DEF_DATA(int) pj_log_max_level = PJ_LOG_MAX_LEVEL; static int pj_log_max_level = PJ_LOG_MAX_LEVEL; #endif +static void *g_last_thread; + #if PJ_HAS_THREADS static long thread_suspended_tls_id = -1; +# if PJ_LOG_ENABLE_INDENT +static long thread_indent_tls_id = -1; +# endif +#endif + +#if !PJ_LOG_ENABLE_INDENT || !PJ_HAS_THREADS +static int log_indent; #endif static pj_log_func *log_writer = &pj_log_write; static unsigned log_decor = PJ_LOG_HAS_TIME | PJ_LOG_HAS_MICRO_SEC | PJ_LOG_HAS_SENDER | PJ_LOG_HAS_NEWLINE | - PJ_LOG_HAS_SPACE + PJ_LOG_HAS_SPACE | PJ_LOG_HAS_THREAD_SWC | + PJ_LOG_HAS_INDENT #if defined(PJ_WIN32) && PJ_WIN32!=0 | PJ_LOG_HAS_COLOR #endif @@ -71,6 +81,8 @@ static pj_color_t PJ_LOG_COLOR_77 = PJ_TERM_COLOR_R | static char log_buffer[PJ_LOG_MAX_SIZE]; #endif +#define LOG_MAX_INDENT 80 + #if PJ_HAS_THREADS static void logging_shutdown(void) { @@ -78,17 +90,82 @@ static void logging_shutdown(void) pj_thread_local_free(thread_suspended_tls_id); thread_suspended_tls_id = -1; } +# if PJ_LOG_ENABLE_INDENT + if (thread_indent_tls_id != -1) { + pj_thread_local_free(thread_indent_tls_id); + thread_indent_tls_id = -1; + } +# endif +} +#endif /* PJ_HAS_THREADS */ + +#if PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS +static void log_set_indent(int indent) +{ + if (indent < 0) indent = 0; + pj_thread_local_set(thread_indent_tls_id, (void*)(long)indent); +} + +static int log_get_raw_indent() +{ + return (long)pj_thread_local_get(thread_indent_tls_id); +} + +#else +static void log_set_indent(int indent) +{ + log_indent = indent; + if (log_indent < 0) log_indent = 0; +} + +static int log_get_raw_indent() +{ + return log_indent; +} +#endif /* PJ_LOG_ENABLE_INDENT && PJ_HAS_THREADS */ + +static int log_get_indent() +{ + int indent = log_get_raw_indent(); + return indent > LOG_MAX_INDENT ? LOG_MAX_INDENT : indent; +} + +PJ_DEF(void) pj_log_add_indent(int indent) +{ + log_set_indent(log_get_raw_indent() + indent); +} + +PJ_DEF(void) pj_log_push_indent(void) +{ + pj_log_add_indent(PJ_LOG_INDENT_SIZE); +} + +PJ_DEF(void) pj_log_pop_indent(void) +{ + pj_log_add_indent(-PJ_LOG_INDENT_SIZE); } -#endif pj_status_t pj_log_init(void) { #if PJ_HAS_THREADS if (thread_suspended_tls_id == -1) { - pj_thread_local_alloc(&thread_suspended_tls_id); + pj_status_t status; + status = pj_thread_local_alloc(&thread_suspended_tls_id); + if (status != PJ_SUCCESS) + return status; + +# if PJ_LOG_ENABLE_INDENT + status = pj_thread_local_alloc(&thread_indent_tls_id); + if (status != PJ_SUCCESS) { + pj_thread_local_free(thread_suspended_tls_id); + thread_suspended_tls_id = -1; + return status; + } +# endif pj_atexit(&logging_shutdown); } #endif + g_last_thread = NULL; return PJ_SUCCESS; } @@ -242,7 +319,7 @@ PJ_DEF(void) pj_log( const char *sender, int level, #if PJ_LOG_USE_STACK_BUFFER char log_buffer[PJ_LOG_MAX_SIZE]; #endif - int saved_level, len, print_len; + int saved_level, len, print_len, indent; PJ_CHECK_STACK(); @@ -276,7 +353,7 @@ PJ_DEF(void) pj_log( const char *sender, int level, pre += 3; } if (log_decor & PJ_LOG_HAS_YEAR) { - *pre++ = ' '; + if (pre!=log_buffer) *pre++ = ' '; pre += pj_utoa(ptime.year, pre); } if (log_decor & PJ_LOG_HAS_MONTH) { @@ -288,7 +365,7 @@ PJ_DEF(void) pj_log( const char *sender, int level, pre += pj_utoa_pad(ptime.day, pre, 2, '0'); } if (log_decor & PJ_LOG_HAS_TIME) { - *pre++ = ' '; + if (pre!=log_buffer) *pre++ = ' '; pre += pj_utoa_pad(ptime.hour, pre, 2, '0'); *pre++ = ':'; pre += pj_utoa_pad(ptime.min, pre, 2, '0'); @@ -302,7 +379,7 @@ PJ_DEF(void) pj_log( const char *sender, int level, if (log_decor & PJ_LOG_HAS_SENDER) { enum { SENDER_WIDTH = 14 }; int sender_len = strlen(sender); - *pre++ = ' '; + if (pre!=log_buffer) *pre++ = ' '; if (sender_len <= SENDER_WIDTH) { while (sender_len < SENDER_WIDTH) *pre++ = ' ', ++sender_len; @@ -334,10 +411,28 @@ PJ_DEF(void) pj_log( const char *sender, int level, if (log_decor != 0 && log_decor != PJ_LOG_HAS_NEWLINE) *pre++ = ' '; - if (log_decor & PJ_LOG_HAS_SPACE) { + if (log_decor & PJ_LOG_HAS_THREAD_SWC) { + void *current_thread = (void*)pj_thread_this(); + if (current_thread != g_last_thread) { + *pre++ = '!'; + g_last_thread = current_thread; + } else { + *pre++ = ' '; + } + } else if (log_decor & PJ_LOG_HAS_SPACE) { *pre++ = ' '; } +#if PJ_LOG_ENABLE_INDENT + if (log_decor & PJ_LOG_HAS_INDENT) { + indent = log_get_indent(); + if (indent > 0) { + pj_memset(pre, PJ_LOG_INDENT_CHAR, indent); + pre += indent; + } + } +#endif + len = pre - log_buffer; /* Print the whole message to the string log_buffer. */ -- cgit v1.2.3