summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2011-09-18 14:38:46 +0000
committerBenny Prijono <bennylp@teluu.com>2011-09-18 14:38:46 +0000
commit8656f9c3676f6be0ad9c1f2603389ffab2dca8d2 (patch)
tree5c01062ddbb74084e8bcf130f49fc69d7947aa4e /pjlib
parentba9693beb7db082c1edd9930db3af1405700ac28 (diff)
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
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/config.h27
-rw-r--r--pjlib/include/pj/log.h23
-rw-r--r--pjlib/src/pj/log.c111
3 files changed, 152 insertions, 9 deletions
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. */