summaryrefslogtreecommitdiff
path: root/main/cli.c
diff options
context:
space:
mode:
authorRussell Bryant <russell@russellbryant.com>2007-07-23 14:21:41 +0000
committerRussell Bryant <russell@russellbryant.com>2007-07-23 14:21:41 +0000
commitf1f72312bbf614f205bef7651f1dea677f58785e (patch)
tree22b55dad3a34eb447cb5783333e6ebad3bec22ce /main/cli.c
parentb1791d9349bd43ae1afd70340e1646138cc47b31 (diff)
(closes issue #10192)
Reported by: bbryant Patches: 20070720__core_debug_by_file.patch uploaded by bbryant (license 36) (with some modifications by me) Tested by: russell, bbryant This set of changes introduces the ability to set the core debug or verbose levels on a per-file basis. Interestingly enough, in 1.4, you have the ability to set core debug for a single file, but that functionality was accidentally lost in the conversion of the CLI commands to the new format. This patch improves upon what was in 1.4 by letting you set it for more than 1 file, and by also supporting verbose. *** Janitor Project *** This patch also introduces a new macro, ast_verb(), which is similar to ast_debug(). Setting the per file verbose value only works for messages that use this macro. Converting existing uses of ast_verbose() can be done like: if (option_debug > 2) ast_verbose(VERBOSE_PREFIX_3 "Something useful\n"); ... ast_verb(3, "Something useful\n"); git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@76555 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/cli.c')
-rw-r--r--main/cli.c129
1 files changed, 126 insertions, 3 deletions
diff --git a/main/cli.c b/main/cli.c
index 235afd2f2..71163bc82 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -49,6 +49,22 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "editline/readline/readline.h"
#include "asterisk/threadstorage.h"
+/*!
+ * \brief map a debug or verbose value to a filename
+ */
+struct ast_debug_file {
+ unsigned int level;
+ AST_RWLIST_ENTRY(ast_debug_file) entry;
+ char filename[0];
+};
+
+AST_RWLIST_HEAD(debug_file_list, ast_debug_file);
+
+/*! list of filenames and their debug settings */
+static struct debug_file_list debug_files;
+/*! list of filenames and their verbose settings */
+static struct debug_file_list verbose_files;
+
AST_THREADSTORAGE(ast_cli_buf);
/*! \brief Initial buffer size for resulting strings in ast_cli() */
@@ -71,6 +87,40 @@ void ast_cli(int fd, const char *fmt, ...)
ast_carefulwrite(fd, buf->str, strlen(buf->str), 100);
}
+unsigned int ast_debug_get_by_file(const char *file)
+{
+ struct ast_debug_file *adf;
+ unsigned int res = 0;
+
+ AST_RWLIST_RDLOCK(&debug_files);
+ AST_LIST_TRAVERSE(&debug_files, adf, entry) {
+ if (!strncasecmp(adf->filename, file, strlen(adf->filename))) {
+ res = adf->level;
+ break;
+ }
+ }
+ AST_RWLIST_UNLOCK(&debug_files);
+
+ return res;
+}
+
+unsigned int ast_verbose_get_by_file(const char *file)
+{
+ struct ast_debug_file *adf;
+ unsigned int res = 0;
+
+ AST_RWLIST_RDLOCK(&verbose_files);
+ AST_LIST_TRAVERSE(&verbose_files, adf, entry) {
+ if (!strncasecmp(adf->filename, file, strlen(file))) {
+ res = adf->level;
+ break;
+ }
+ }
+ AST_RWLIST_UNLOCK(&verbose_files);
+
+ return res;
+}
+
static AST_LIST_HEAD_STATIC(helpers, ast_cli_entry);
static const char logger_mute_help[] =
@@ -184,6 +234,23 @@ static char *handle_reload_deprecated(struct ast_cli_entry *e, int cmd, struct a
return s;
}
+/*!
+ * \brief Find the debug or verbose file setting
+ * \arg debug 1 for debug, 0 for verbose
+ */
+static struct ast_debug_file *find_debug_file(const char *fn, unsigned int debug)
+{
+ struct ast_debug_file *df = NULL;
+ struct debug_file_list *dfl = debug ? &debug_files : &verbose_files;
+
+ AST_LIST_TRAVERSE(dfl, df, entry) {
+ if (!strcasecmp(df->filename, fn))
+ break;
+ }
+
+ return df;
+}
+
static char *handle_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
{
int oldval;
@@ -194,14 +261,18 @@ static char *handle_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
char **argv = a->argv;
int *dst;
char *what;
+ struct debug_file_list *dfl;
+ struct ast_debug_file *adf;
+ char *fn;
switch (cmd) {
case CLI_INIT:
e->command = "core set {debug|verbose} [off|atleast]";
e->usage =
- "Usage: core set {debug|verbose} [atleast] <level>\n"
+ "Usage: core set {debug|verbose} [atleast] <level> [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;
@@ -225,15 +296,67 @@ static char *handle_verbose(struct ast_cli_entry *e, int cmd, struct ast_cli_arg
what = "Verbosity";
}
if (argc == e->args && !strcasecmp(argv[e->args - 1], "off")) {
+ unsigned int debug = (*what == 'C');
newlevel = 0;
+
+ dfl = debug ? &debug_files : &verbose_files;
+
+ AST_RWLIST_WRLOCK(dfl);
+ while ((adf = AST_RWLIST_REMOVE_HEAD(dfl, entry)))
+ ast_free(adf);
+ ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
+ AST_RWLIST_UNLOCK(dfl);
+
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) {
+ unsigned int debug = (*what == 'C');
+ dfl = debug ? &debug_files : &verbose_files;
+
+ fn = argv[e->args + atleast];
+
+ AST_RWLIST_WRLOCK(dfl);
+
+ if ((adf = find_debug_file(fn, debug)) && !newlevel) {
+ AST_RWLIST_REMOVE(dfl, adf, entry);
+ if (AST_RWLIST_EMPTY(dfl))
+ ast_clear_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
+ AST_RWLIST_UNLOCK(dfl);
+ ast_cli(fd, "%s was %d and has been set to 0 for '%s'\n", what, adf->level, fn);
+ ast_free(adf);
+ 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_RWLIST_UNLOCK(dfl);
+ return CLI_SUCCESS;
+ }
+ } else if (!(adf = ast_calloc(1, sizeof(*adf) + strlen(fn) + 1))) {
+ AST_RWLIST_UNLOCK(dfl);
+ return CLI_FAILURE;
+ }
+
+ oldval = adf->level;
+ adf->level = newlevel;
+ strcpy(adf->filename, fn);
+
+ ast_set_flag(&ast_options, debug ? AST_OPT_FLAG_DEBUG_FILE : AST_OPT_FLAG_VERBOSE_FILE);
+
+ AST_RWLIST_INSERT_TAIL(dfl, adf, entry);
+ AST_RWLIST_UNLOCK(dfl);
+
+ ast_cli(fd, "%s was %d and has been set to %d for '%s'\n", what, oldval, adf->level, adf->filename);
+
+ return CLI_SUCCESS;
+ }
done:
if (!atleast || newlevel > *dst)