From 4dfc60f56374ebea3fd3fc2e1566214c0b776738 Mon Sep 17 00:00:00 2001 From: Matthieu Patou Date: Sun, 19 May 2013 10:02:14 -0700 Subject: [PATCH] param: add debug header template This parameter allow to customize the header that we put in the log, it can also be used so that we have some headers when logging to stdout Signed-off-by: Matthieu Patou --- lib/param/loadparm.c | 3 +- lib/param/param_functions.c | 1 + lib/param/param_table.c | 9 ++ lib/util/debug.c | 238 +++++++++++++++++++++++++++++++++++--------- lib/util/debug.h | 1 + lib/util/debug_s3.c | 2 + source3/include/proto.h | 1 + 7 files changed, 207 insertions(+), 48 deletions(-) diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index fdb02c3..a36b642 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -500,7 +500,7 @@ const char **lpcfg_parm_string_list(TALLOC_CTX *mem_ctx, const char *value = lpcfg_get_parametric(lp_ctx, service, type, option); if (value != NULL) - return (const char **)str_list_make(mem_ctx, value, separator); + return (const char * const *)str_list_make(mem_ctx, value, separator); return NULL; } @@ -2219,6 +2219,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "allow dns updates", "secure only"); lpcfg_do_global_parameter(lp_ctx, "dns forwarder", ""); + lpcfg_do_global_parameter(lp_ctx, "debug header template", ""); for (i = 0; parm_table[i].label; i++) { if (!(lp_ctx->flags[i] & FLAG_CMDLINE)) { diff --git a/lib/param/param_functions.c b/lib/param/param_functions.c index 6fc7801..d4272ef 100644 --- a/lib/param/param_functions.c +++ b/lib/param/param_functions.c @@ -234,6 +234,7 @@ FN_GLOBAL_BOOL(wins_proxy, bWINSproxy) FN_GLOBAL_CONST_STRING(afs_username_map, szAfsUsernameMap) FN_GLOBAL_CONST_STRING(ctdbd_socket, ctdbdSocket) FN_GLOBAL_CONST_STRING(dedicated_keytab_file, szDedicatedKeytabFile) +FN_GLOBAL_CONST_STRING(debug_header_template, szDebugHeader) FN_GLOBAL_CONST_STRING(dnsdomain, szRealm_lower) FN_GLOBAL_CONST_STRING(dns_forwarder, dns_forwarder) FN_GLOBAL_CONST_STRING(dos_charset, dos_charset) diff --git a/lib/param/param_table.c b/lib/param/param_table.c index c65a738..02fa6fc 100644 --- a/lib/param/param_table.c +++ b/lib/param/param_table.c @@ -1266,6 +1266,15 @@ static struct parm_struct parm_table[] = { .enum_list = NULL, .flags = FLAG_ADVANCED, }, + { + .label = "debug header template", + .type = P_STRING, + .p_class = P_GLOBAL, + .offset = GLOBAL_VAR(szDebugHeader), + .special = NULL, + .enum_list = NULL, + .flags = FLAG_ADVANCED, + }, {N_("Protocol Options"), P_SEP, P_SEPARATOR}, diff --git a/lib/util/debug.c b/lib/util/debug.c index 34aa76f..020eeb6 100644 --- a/lib/util/debug.c +++ b/lib/util/debug.c @@ -929,6 +929,137 @@ void dbgflush( void ) bufr_print(); } +static bool dbgexpandtemplateparams(char *dest, const char *debug_header_template, + unsigned int size, int level, int cls, + const char* loc, const char* func) +{ + const char *chr = debug_header_template; + unsigned int i = 0; + int l; + dest[0] = '\0'; + + memset(dest, 0, size); + while (*chr) { + if (i >= size) + return false; + + if (*chr == '%') { + chr++; + if (*chr && *chr != '%') { + switch(*chr) { + case 'p': + /* PID */ + l = snprintf(dest + i, size - 1 - i, + "%u", + (unsigned int)getpid()); + i += l; + break; + case 't': + { + /* Timestamp */ + char* time_str = current_timestring(NULL, + state.settings.debug_hires_timestamp); + l = snprintf(dest + i, size - 1 - i, + "%s", time_str); + talloc_free(time_str); + i += l; + } + break; + case 'l': + /* log level */ + l = snprintf(dest + i, size - 1 - i, + "%2d", level); + i += l; + break; + case 'F': + /* Location */ + l = snprintf(dest + i, size - 1 - i, + "%s", loc); + i += l; + break; + case 'f': + /* Function */ + l = snprintf(dest + i, size - 1 - i, + "%s", func); + i += l; + break; + case 'u': + /* Uid */ + l = snprintf(dest + i, size - 1 - i, + "%u", + (unsigned int)getuid()); + i += l; + break; + case 'U': + /* Euid */ + l = snprintf(dest + i, size - 1 - i, + "%u", + (unsigned int)geteuid()); + i += l; + break; + case 'g': + /* Gid */ + l = snprintf(dest + i, size - 1 - i, + "%u", + (unsigned int)getgid()); + i += l; + break; + case 'G': + l = snprintf(dest + i, size - 1 - i, + "%u", + (unsigned int)getegid()); + i += l; + /* Egid */ + break; + case 'c': + /* class */ + l = snprintf(dest + i, size - 1 - i, + "%s", + default_classname_table[cls]); + l += i; + break; + default: + break; + } + chr++; + } else { + if (*chr) { + chr++; + } + dest[i] = '%'; + i++; + dest[i] = '%'; + i++; + } + } else { + if (*chr == '\\' && *(chr + 1) != '\\') { + chr++; + switch(*chr) { + case 'n': + dest[i++] = '\n'; + break; + case 'r': + dest[i++] = '\r'; + break; + case 's': + dest[i++] = ' '; + break; + case 't': + dest[i++] = '\t'; + break; + default: + break; + } + } else { + dest[i++] = *chr; + } + chr++; + } + } + + return true; +} + /*************************************************************************** Print a Debug Header. @@ -956,6 +1087,7 @@ bool dbghdrclass(int level, int cls, const char *location, const char *func) { /* Ensure we don't lose any real errno value. */ int old_errno = errno; + char debug_header_template[200] = {0}; if( format_pos ) { /* This is a fudge. If there is stuff sitting in the format_bufr, then @@ -973,61 +1105,73 @@ bool dbghdrclass(int level, int cls, const char *location, const char *func) /* Set current_msg_level. */ current_msg_level = level; - /* Don't print a header if we're logging to stdout. */ - if ( state.logtype != DEBUG_FILE ) { - return( true ); - } + if (!state.settings.debug_header_template || + (*(state.settings.debug_header_template) == '\0')) + { + char common_header[60] = {0}; + /* Current size should be 57 at most right now but let's leave some room for futur */ + unsigned int len = 0; - /* Print the header if timestamps are turned on. If parameters are - * not yet loaded, then default to timestamps on. - */ - if( state.settings.timestamp_logs || state.settings.debug_prefix_timestamp) { - bool verbose = false; - char header_str[200]; + /* Don't print a header if we're logging to stdout. */ + if ( state.logtype != DEBUG_FILE ) { + return( true ); + } + /* + * Print the header if timestamps are turned on. If parameters are + * not yet loaded, then default to timestamps on. + */ + if (state.settings.timestamp_logs || state.settings.debug_prefix_timestamp) { + bool verbose = false; - header_str[0] = '\0'; + if (unlikely(DEBUGLEVEL_CLASS[cls] >= 10)) { + verbose = true; + } - if (unlikely(DEBUGLEVEL_CLASS[ cls ] >= 10)) { - verbose = true; - } + if (verbose || state.settings.debug_pid) { + strncpy(common_header, "[%t, %l, pid=%p", sizeof(common_header)); + } else { + strncpy(common_header, "[%t, %l", sizeof(common_header)); + } + len = strlen(common_header); - if (verbose || state.settings.debug_pid) - slprintf(header_str,sizeof(header_str)-1,", pid=%u",(unsigned int)getpid()); + if (verbose || state.settings.debug_uid) { + slprintf(common_header + len, + sizeof(common_header) - 1 - len, + ", effective(%%u,%%g), real(%%U,%%G)"); + len = strlen(common_header); + } - if (verbose || state.settings.debug_uid) { - size_t hs_len = strlen(header_str); - slprintf(header_str + hs_len, - sizeof(header_str) - 1 - hs_len, - ", effective(%u, %u), real(%u, %u)", - (unsigned int)geteuid(), (unsigned int)getegid(), - (unsigned int)getuid(), (unsigned int)getgid()); - } + if ((verbose || state.settings.debug_class) + && (cls != DBGC_ALL)) + { + slprintf(common_header + len, + sizeof(common_header) - 1 - len, + ", class=%%c"); + len = strlen(common_header); + } - if ((verbose || state.settings.debug_class) - && (cls != DBGC_ALL)) { - size_t hs_len = strlen(header_str); - slprintf(header_str + hs_len, - sizeof(header_str) -1 - hs_len, - ", class=%s", - classname_table[cls]); + strncpy(debug_header_template, common_header, sizeof(debug_header_template)); + /* Print it all out at once to prevent split syslog output. */ + if (state.settings.debug_prefix_timestamp) { + slprintf(debug_header_template + len, sizeof(debug_header_template) - 1 - len, + "] "); + } else { + slprintf(debug_header_template + len, sizeof(debug_header_template) - 1 - len, + "] %%F(%%f)\n"); + } } + } else { + strncpy(debug_header_template, state.settings.debug_header_template, + sizeof(debug_header_template)); + } - /* Print it all out at once to prevent split syslog output. */ - if( state.settings.debug_prefix_timestamp ) { - char *time_str = current_timestring(NULL, - state.settings.debug_hires_timestamp); - (void)Debug1( "[%s, %2d%s] ", - time_str, - level, header_str); - talloc_free(time_str); - } else { - char *time_str = current_timestring(NULL, - state.settings.debug_hires_timestamp); - (void)Debug1( "[%s, %2d%s] %s(%s)\n", - time_str, - level, header_str, location, func ); - talloc_free(time_str); - } + if (*debug_header_template) { + char header_str[200] = {0}; + dbgexpandtemplateparams((char *)header_str, + debug_header_template, + sizeof(header_str), + level, cls, location, func); + Debug1("%s", header_str); } errno = old_errno; diff --git a/lib/util/debug.h b/lib/util/debug.h index feea0a8..d1c7d19 100644 --- a/lib/util/debug.h +++ b/lib/util/debug.h @@ -211,6 +211,7 @@ struct debug_settings { bool debug_pid; bool debug_uid; bool debug_class; + char *debug_header_template; }; void setup_logging(const char *prog_name, enum debug_logtype new_logtype); diff --git a/lib/util/debug_s3.c b/lib/util/debug_s3.c index ccf577f..8573846 100644 --- a/lib/util/debug_s3.c +++ b/lib/util/debug_s3.c @@ -42,6 +42,8 @@ bool reopen_logs(void) settings.debug_pid = lp_debug_pid(); settings.debug_uid = lp_debug_uid(); settings.debug_class = lp_debug_class(); + settings.debug_header_template = talloc_strdup(talloc_tos(), + lp_debug_header_template()); debug_set_settings(&settings); } return reopen_logs_internal(); diff --git a/source3/include/proto.h b/source3/include/proto.h index 83ab77a..4d8deca 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1485,6 +1485,7 @@ char* lp_perfcount_module(TALLOC_CTX *ctx); void widelinks_warning(int snum); const char *lp_ncalrpc_dir(void); void _lp_set_server_role(int server_role); +const char* lp_debug_header_template(void); /* The following definitions come from param/loadparm_ctx.c */ -- 1.8.1.2