Index: include/asterisk/options.h =================================================================== --- include/asterisk/options.h (revision 76170) +++ include/asterisk/options.h (working copy) @@ -20,6 +20,9 @@ * \brief Options provided by main asterisk program */ +#include "asterisk/logger.h" +#include "asterisk/linkedlists.h" + #ifndef _ASTERISK_OPTIONS_H #define _ASTERISK_OPTIONS_H @@ -109,6 +112,7 @@ extern int option_verbose; extern int option_maxfiles; /*!< Max number of open file handles (files, sockets) */ extern int option_debug; /*!< Debugging */ +extern AST_LIST_HEAD(debug_file_list, ast_debug_file) debug_file_list, verbose_file_list; extern int option_maxcalls; /*!< Maximum number of simultaneous channels */ extern double option_maxload; #if defined(HAVE_SYSINFO) Index: include/asterisk/logger.h =================================================================== --- include/asterisk/logger.h (revision 76170) +++ include/asterisk/logger.h (working copy) @@ -59,6 +59,15 @@ \param function Will be provided by the LOG_* macro \param fmt This is what is important. The format is the same as your favorite breed of printf. You know how that works, right? :-) */ +struct ast_debug_file { + int level; + struct { struct ast_debug_file *next; } entry; /* can't include header for AST_LIST_ENTRY in this file */ + char filename[0]; +}; + +struct ast_debug_file *ast_debug_get_by_file(const char *file); +struct ast_debug_file *ast_verbose_get_by_file(const char *file); + void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf, 5, 6))); @@ -135,11 +144,18 @@ * to get logged */ #define ast_debug(level, ...) do { \ - if (option_debug >= (level)) { \ + struct ast_debug_file *adf = ast_debug_get_by_file(__FILE__); \ + if ((adf && *(int *)adf >= (level)) || option_debug >= (level)) { \ ast_log(LOG_DEBUG, __VA_ARGS__); \ } \ } while (0) +#define ast_verb(level, ...) do { \ + struct ast_debug_file *adf = ast_verbose_get_by_file(__FILE__); \ + if((adf && *(int *)adf >= level) || option_verbose >= level) \ + ast_verbose(__VA_ARGS__); \ +} while (0) + #if defined(__cplusplus) || defined(c_plusplus) } #endif Index: main/asterisk.c =================================================================== --- main/asterisk.c (revision 76170) +++ main/asterisk.c (working copy) @@ -163,7 +163,8 @@ int option_verbose; /*!< Verbosity level */ int option_debug; /*!< Debug level */ - +struct debug_file_list debug_file_list = AST_LIST_HEAD_INIT_VALUE; /*!< List of files where ast_debug will select from */ +struct debug_file_list verbose_file_list = AST_LIST_HEAD_INIT_VALUE; /*!< List of files where ast_verb will select from */ double option_maxload; /*!< Max load avg on system */ int option_maxcalls; /*!< Max number of active calls */ int option_maxfiles; /*!< Max number of open file handles (files, sockets) */ Index: main/cli.c =================================================================== --- main/cli.c (revision 76170) +++ main/cli.c (working copy) @@ -194,14 +194,19 @@ char **argv = a->argv; int *dst; char *what; + struct debug_file_list *dfl; + struct ast_debug_file *adf; + char *fn; + struct ast_debug_file *(*dfl_search)(const char *); switch (cmd) { case CLI_INIT: e->command = "core set {debug|verbose} [off|atleast]"; e->usage = - "Usage: core set {debug|verbose} [atleast] \n" + "Usage: core set {debug|verbose} [atleast] [filename]\n" " core set {debug|verbose} off\n" - " Sets level of debug or verbose messages to be displayed.\n" + " Sets level of debug or verbose messages to be displayed or \n" + " sets a filename to display debug messages from.\n" " 0 or off means no messages should be displayed.\n" " Equivalent to -d[d[...]] or -v[v[v...]] on startup\n"; return NULL; @@ -226,15 +231,62 @@ } if (argc == e->args && !strcasecmp(argv[e->args - 1], "off")) { newlevel = 0; + + dfl = (*what == 'C') ? &debug_file_list : &verbose_file_list; + + while (AST_LIST_EMPTY(dfl)) + AST_LIST_REMOVE_HEAD(dfl, entry); + goto done; } if (!strcasecmp(argv[e->args-1], "atleast")) atleast = 1; - if (argc != e->args + atleast) + if (argc != e->args + atleast && argc != e->args + atleast + 1) return CLI_SHOWUSAGE; if (sscanf(argv[e->args + atleast - 1], "%d", &newlevel) != 1) return CLI_SHOWUSAGE; + if (argc == e->args + atleast + 1) { + if (*what == 'C') { + dfl = &debug_file_list; + dfl_search = ast_debug_get_by_file; + } else { + dfl = &verbose_file_list; + dfl_search = ast_verbose_get_by_file; + } + fn = argv[e->args + atleast]; + + AST_LIST_LOCK(dfl); + + if ((adf = dfl_search(fn)) && !newlevel) { + AST_LIST_REMOVE(dfl, adf, entry); + ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, adf->level, fn); + AST_LIST_UNLOCK(dfl); + return CLI_SUCCESS; + } + + if (adf) { + if ((atleast && newlevel < adf->level) || adf->level == newlevel) { + ast_cli(fd, "%s is %d for '%s'\n", what, adf->level, fn); + AST_LIST_UNLOCK(dfl); + return CLI_SUCCESS; + } + } else if (!(adf = ast_calloc(1, sizeof(*adf)+strlen(fn)+1))) { + AST_LIST_UNLOCK(dfl); + return CLI_FAILURE; + } + + oldval = adf->level; + adf->level = newlevel; + strcpy(adf->filename, fn); + + AST_LIST_INSERT_TAIL(dfl, adf, entry); + + ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, adf->level, adf->filename); + AST_LIST_UNLOCK(dfl); + return CLI_SUCCESS; + } + done: if (!atleast || newlevel > *dst) *dst = newlevel; Index: main/logger.c =================================================================== --- main/logger.c (revision 76170) +++ main/logger.c (working copy) @@ -70,6 +70,7 @@ #include "asterisk/manager.h" #include "asterisk/threadstorage.h" #include "asterisk/strings.h" +#include "asterisk/linkedlists.h" #if defined(__linux__) && !defined(__NR_gettid) #include @@ -81,7 +82,28 @@ #define GETTID() getpid() #endif +struct ast_debug_file *ast_debug_get_by_file(const char *file) { + struct ast_debug_file *adf; + AST_LIST_TRAVERSE(&debug_file_list, adf, entry) { + if (!strcasecmp(adf->filename, file)) + return adf; + } + + return NULL; +} + +struct ast_debug_file *ast_verbose_get_by_file(const char *file) { + struct ast_debug_file *adf; + + AST_LIST_TRAVERSE(&verbose_file_list, adf, entry) { + if (!strncasecmp(adf->filename, file, strlen(file))) + return adf; + } + + return NULL; +} + static char dateformat[256] = "%b %e %T"; /* Original Asterisk Format */ static char queue_log_name[256] = QUEUELOG;