Browse Source

Merge pull request #462 from smititelu/KAMAILIO-33

debugger: add fifos to set/get level/facility
Stefan Mititelu 9 năm trước cách đây
mục cha
commit
06a6ee170b

+ 15 - 1
dprint.c

@@ -90,13 +90,27 @@ int str2facility(char *s)
 {
 	int i;
 
-	for( i=0; str_fac[i] ; i++) {
+	for (i=0; str_fac[i]; i++) {
 		if (!strcasecmp(s,str_fac[i]))
 			return int_fac[i];
 	}
 	return -1;
 }
 
+char* facility2str(int fl, int *len)
+{
+	int i;
+
+	for (i=0; str_fac[i]; i++) {
+		if (fl == int_fac[i]) {
+			*len = strlen(str_fac[i]);
+			return str_fac[i];
+		}
+	}
+
+	return NULL;
+}
+
 /* fixup function for log_facility cfg parameter */
 int log_facility_fixup(void *handle, str *gname, str *name, void **val)
 {

+ 2 - 0
dprint.h

@@ -160,6 +160,8 @@ extern volatile int dprint_crit;
 #endif
 
 int str2facility(char *s);
+char* facility2str(int fl, int *len);
+
 int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 
 void dprint_color(int level);

+ 1 - 0
modules/debugger/Makefile

@@ -10,4 +10,5 @@ DEFS+=-DKAMAILIO_MOD_INTERFACE
 
 SERLIBPATH=../../lib
 SER_LIBS+=$(SERLIBPATH)/srutils/srutils
+SER_LIBS+=$(SERLIBPATH)/kmi/kmi
 include ../../Makefile.modules

+ 117 - 8
modules/debugger/debugger_api.c

@@ -981,12 +981,12 @@ static void  dbg_rpc_trace(rpc_t* rpc, void* ctx)
 /**
  *
  */
-static const char* dbg_rpc_mod_level_doc[2] = {
-	"Specify module log level",
+static const char* dbg_rpc_set_mod_level_doc[2] = {
+	"Set module log level",
 	0
 };
 
-static void dbg_rpc_mod_level(rpc_t* rpc, void* ctx){
+static void dbg_rpc_set_mod_level(rpc_t* rpc, void* ctx){
 	int l;
 	str value = {0,0};
 
@@ -1007,12 +1007,12 @@ static void dbg_rpc_mod_level(rpc_t* rpc, void* ctx){
 /**
  *
  */
-static const char* dbg_rpc_mod_facility_doc[2] = {
-	"Specify module log facility",
+static const char* dbg_rpc_set_mod_facility_doc[2] = {
+	"Set module log facility",
 	0
 };
 
-static void dbg_rpc_mod_facility(rpc_t* rpc, void* ctx) {
+static void dbg_rpc_set_mod_facility(rpc_t* rpc, void* ctx) {
 	int fl;
 	str value = {0, 0};
 	str facility = {0, 0};
@@ -1036,6 +1036,55 @@ static void dbg_rpc_mod_facility(rpc_t* rpc, void* ctx) {
 	rpc->add(ctx, "s", "200 ok");
 }
 
+/**
+ *
+ */
+static const char* dbg_rpc_get_mod_level_doc[2] = {
+	"Get module log level",
+	0
+};
+
+static void dbg_rpc_get_mod_level(rpc_t* rpc, void* ctx){
+	int l;
+	str value = {0,0};
+
+	if (rpc->scan(ctx, "S", &value) < 1)
+	{
+		rpc->fault(ctx, 500, "invalid parameters");
+		return;
+	}
+
+	l = get_debug_level(value.s, value.len);
+
+	rpc->add(ctx, "d", l);
+}
+
+/**
+ *
+ */
+static const char* dbg_rpc_get_mod_facility_doc[2] = {
+	"Get module log facility",
+	0
+};
+
+static void dbg_rpc_get_mod_facility(rpc_t* rpc, void* ctx) {
+	int fl;
+	str value = {0, 0};
+	str facility = {0, 0};
+
+	if (rpc->scan(ctx, "S", &value) < 1)
+	{
+	    rpc->fault(ctx, 500, "invalid parameters");
+	    return;
+	}
+
+	fl = get_debug_facility(value.s, value.len);
+	facility.s = facility2str(fl, &facility.len);
+
+	rpc->add(ctx, "S", &facility);
+}
+
+
 /**
  *
  */
@@ -1076,8 +1125,10 @@ rpc_export_t dbg_rpc[] = {
 	{"dbg.bp",        dbg_rpc_bp,        dbg_rpc_bp_doc,        0},
 	{"dbg.ls",        dbg_rpc_list,      dbg_rpc_list_doc,      0},
 	{"dbg.trace",     dbg_rpc_trace,     dbg_rpc_trace_doc,     0},
-	{"dbg.mod_level", dbg_rpc_mod_level, dbg_rpc_mod_level_doc, 0},
-	{"dbg.mod_facility", dbg_rpc_mod_facility, dbg_rpc_mod_facility_doc, 0},
+	{"dbg.set_mod_level", dbg_rpc_set_mod_level, dbg_rpc_set_mod_level_doc, 0},
+	{"dbg.set_mod_facility", dbg_rpc_set_mod_facility, dbg_rpc_set_mod_facility_doc, 0},
+	{"dbg.get_mod_level", dbg_rpc_get_mod_level, dbg_rpc_get_mod_level_doc, 0},
+	{"dbg.get_mod_facility", dbg_rpc_get_mod_facility, dbg_rpc_get_mod_facility_doc, 0},
 	{"dbg.reset_msgid", dbg_rpc_reset_msgid, dbg_rpc_reset_msgid_doc, 0},
 	{0, 0, 0, 0}
 };
@@ -1138,6 +1189,7 @@ int dbg_init_mod_levels(int dbg_mod_hash_size)
 		return -1;
 	}
 	memset(_dbg_mod_table, 0, _dbg_mod_table_size*sizeof(dbg_mod_slot_t));
+	LM_DBG("Created _dbg_mod_table, size %d\n", _dbg_mod_table_size);
 
 	for(i=0; i<_dbg_mod_table_size; i++)
 	{
@@ -1160,6 +1212,63 @@ int dbg_init_mod_levels(int dbg_mod_hash_size)
 	return 0;
 }
 
+/**
+ *
+ */
+int dbg_destroy_mod_levels()
+{
+	int i;
+	dbg_mod_level_t *itl = NULL;
+	dbg_mod_level_t *itlp = NULL;
+
+	dbg_mod_facility_t *itf = NULL;
+	dbg_mod_facility_t *itfp = NULL;
+
+	if (_dbg_mod_table_size <= 0)
+		return 0;
+
+	if (_dbg_mod_table == NULL)
+		return 0;
+
+	for (i = 0; i < _dbg_mod_table_size; i++) {
+		// destroy level list
+		lock_get(&_dbg_mod_table[i].lock);
+		itl = _dbg_mod_table[i].first;
+		while (itl) {
+			itlp = itl;
+			itl = itl->next;
+			shm_free(itlp);
+		}
+		lock_release(&_dbg_mod_table[i].lock);
+
+		// destroy facility list
+		lock_get(&_dbg_mod_table[i].lock_ft);
+		itf = _dbg_mod_table[i].first_ft;
+		while (itf) {
+			itfp = itf;
+			itf = itf->next;
+			shm_free(itfp);
+		}
+		lock_release(&_dbg_mod_table[i].lock_ft);
+
+		// destroy locks
+		lock_destroy(&_dbg_mod_table[i].lock);
+		lock_destroy(&_dbg_mod_table[i].lock_ft);
+
+		// reset all
+		_dbg_mod_table[i].first = NULL;
+		_dbg_mod_table[i].first_ft = NULL;
+	}
+
+	// free table
+	shm_free(_dbg_mod_table);
+	_dbg_mod_table = NULL;
+
+	LM_DBG("Destroyed _dbg_mod_table, size %d\n", _dbg_mod_table_size);
+
+	return 0;
+}
+
 /*
  * case insensitive hashing - clone here to avoid usage of LOG*()
  * - s1 - str to hash

+ 1 - 0
modules/debugger/debugger_api.h

@@ -34,6 +34,7 @@ int dbg_init_mypid(void);
 int dbg_init_rpc(void);
 
 int dbg_init_mod_levels(int _dbg_mod_hash_size);
+int dbg_destroy_mod_levels();
 int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel);
 int dbg_set_mod_debug_facility(char *mname, int mnlen, int *mfacility);
 void dbg_enable_mod_levels(void);

+ 271 - 1
modules/debugger/debugger_mod.c

@@ -28,6 +28,8 @@
 #include <string.h>
 
 #include "../cfgt/cfgt.h"
+#include "../../lib/kmi/mi.h"
+#include "../../lib/kmi/tree.h"
 #include "../../sr_module.h"
 #include "../../dprint.h"
 #include "../../ut.h"
@@ -61,6 +63,12 @@ static int w_dbg_sip_msg(struct sip_msg* msg, char *level, char *facility);
 
 extern char* dump_lump_list(struct lump *list, int s_offset, char *s_buf);
 
+/* mi commands */
+static struct mi_root* mi_set_dbg_mod_level(struct mi_root *cmd_tree, void *param);
+static struct mi_root* mi_set_dbg_mod_facility(struct mi_root *cmd_tree, void *param);
+static struct mi_root* mi_get_dbg_mod_level(struct mi_root *cmd_tree, void *param);
+static struct mi_root* mi_get_dbg_mod_facility(struct mi_root *cmd_tree, void *param);
+
 /* parameters */
 extern int _dbg_cfgtrace;
 extern int _dbg_cfgpkgcheck;
@@ -120,13 +128,21 @@ static param_export_t params[]={
 	{0, 0, 0}
 };
 
+static mi_export_t mi_cmds[] = {
+	{"set_dbg_mod_level",         mi_set_dbg_mod_level, 0, 0, 0},
+	{"set_dbg_mod_facility",      mi_set_dbg_mod_facility, 0, 0, 0},
+	{"get_dbg_mod_level",         mi_get_dbg_mod_level, 0, 0, 0},
+	{"get_dbg_mod_facility",      mi_get_dbg_mod_facility, 0, 0, 0},
+	{ 0, 0, 0, 0, 0}
+};
+
 struct module_exports exports = {
 	"debugger",
 	DEFAULT_DLFLAGS, /* dlopen flags */
 	cmds,
 	params,
 	0,
-	0,              /* exported MI functions */
+	mi_cmds,        /* exported MI functions */
 	0,              /* exported pseudo-variables */
 	0,              /* extra processes */
 	mod_init,       /* module initialization function */
@@ -136,6 +152,253 @@ struct module_exports exports = {
 };
 
 
+static struct mi_root* mi_set_dbg_mod_level(struct mi_root *cmd_tree, void *param) {
+	struct mi_node *node;
+	str mod_str, level_str;
+	int l;
+
+	/* get first param */
+	node = cmd_tree->node.kids;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get module str */
+	mod_str = node->value;
+
+	/* get second param */
+	node = node->next;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get level str */
+	level_str = node->value;
+
+	/* no further params expected */
+	node = node->next;
+	if (node != NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	/* get level int */
+	if (str2sint(&level_str, &l) < 0) {
+		LM_ERR("invalid parameter - level value: %.*s\n",
+			level_str.len, level_str.s);
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* set level int */
+	if (default_dbg_cfg.mod_hash_size <= 0 || default_dbg_cfg.mod_level_mode <= 0) {
+		LM_ERR("can't set level for module=%.*s; enable mod_hash_size and mod_level_mode config parameters!\n",
+			mod_str.len, mod_str.s);
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
+	} else if (dbg_set_mod_debug_level(mod_str.s, mod_str.len, &l) < 0) {
+		LM_ERR("failed set level for module=%.*s\n", mod_str.len, mod_str.s);
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
+	} else {
+		LM_DBG("module=%.*s level_str=%.*s level_int=%d\n",
+			mod_str.len, mod_str.s, level_str.len, level_str.s, l);
+	}
+
+	return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+}
+
+static struct mi_root* mi_set_dbg_mod_facility(struct mi_root *cmd_tree, void *param) {
+	struct mi_node *node;
+	str mod_str, facility_str;
+	int fl;
+
+	/* get first param */
+	node = cmd_tree->node.kids;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get module str */
+	mod_str = node->value;
+
+	/* get second param */
+	node = node->next;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get facility str */
+	facility_str = node->value;
+
+	/* no further params expected */
+	node = node->next;
+	if (node != NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	/* get facility int */
+	facility_str.s[facility_str.len] = '\0';
+	if ((fl = str2facility(facility_str.s)) == -1) {
+		LM_ERR("invalid parameter - facility value: %.*s\n",
+			facility_str.len, facility_str.s);
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* set facility int */
+	if (default_dbg_cfg.mod_hash_size <= 0 || default_dbg_cfg.mod_facility_mode <= 0) {
+		LM_ERR("can't set facility for module=%.*s; enable mod_hash_size and mod_facility_mode config parameters!\n",
+			mod_str.len, mod_str.s);
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
+	} else if (dbg_set_mod_debug_facility(mod_str.s, mod_str.len, &fl) < 0) {
+		LM_ERR("failed set facility for module=%.*s\n", mod_str.len, mod_str.s);
+		return init_mi_tree(500, MI_INTERNAL_ERR_S, MI_INTERNAL_ERR_LEN);
+	} else {
+		LM_DBG("module=%.*s facility_str=%.*s facility_int=%d\n",
+			mod_str.len, mod_str.s, facility_str.len, facility_str.s, fl);
+	}
+
+	return init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+}
+
+static struct mi_root* mi_get_dbg_mod_level(struct mi_root *cmd_tree, void *param) {
+	struct mi_node *node, *crt_node;
+	struct mi_root *root = NULL;
+	struct mi_attr *attr;
+	int l;
+	str mod_str, level_str;
+	str level_attr = {"level", strlen("level")};
+
+	/* get first param */
+	node = cmd_tree->node.kids;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get module str */
+	mod_str = node->value;
+
+	/* no further params expected */
+	node = node->next;
+	if (node != NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	/* get module log level */
+	l = get_debug_level(mod_str.s, mod_str.len);
+	level_str.s = sint2str(l, &level_str.len);
+	LM_DBG("module=%.*s level_str=%.*s level_int=%d\n",
+		mod_str.len, mod_str.s, level_str.len, level_str.s, l);
+
+	/* return module log level */
+	root = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+	if (!root) {
+		LM_ERR("the MI tree cannot be initialized!\n");
+		goto error;
+	}
+	node = &root->node;
+
+	if (!(crt_node = add_mi_node_child(node, 0, mod_str.s, mod_str.len, 0, 0)) ) {
+		LM_ERR("cannot add the child node to the tree\n");
+		goto error;
+	}
+
+	if ((attr = add_mi_attr(crt_node, MI_DUP_VALUE,
+	    level_attr.s, level_attr.len,
+	    level_str.s, level_str.len)) == 0) {
+		LM_ERR("cannot add attributes to the node\n");
+		goto error;
+	}
+
+	return root;
+
+error:
+	if (root) {
+		free_mi_tree(root);
+	}
+
+	return NULL;
+}
+
+static struct mi_root* mi_get_dbg_mod_facility(struct mi_root *cmd_tree, void *param) {
+	struct mi_node *node, *crt_node;
+	struct mi_root *root = NULL;
+	struct mi_attr *attr;
+	int fl;
+	str mod_str, facility_str;
+	str facility_attr = {"facility", strlen("facility")};
+
+	/* get first param */
+	node = cmd_tree->node.kids;
+	if (node == NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	if (node->value.s == NULL || node->value.len == 0) {
+		return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
+	}
+
+	/* get module str */
+	mod_str = node->value;
+
+	/* no further params expected */
+	node = node->next;
+	if (node != NULL) {
+		return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
+	}
+
+	/* get module log facility */
+	fl = get_debug_facility(mod_str.s, mod_str.len);
+	facility_str.s = facility2str(fl, &facility_str.len);
+	LM_DBG("module=%.*s facility_str=%.*s facility_int=%d\n",
+		mod_str.len, mod_str.s, facility_str.len, facility_str.s, fl);
+
+	/* return module log facility */
+	root = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
+	if (!root) {
+		LM_ERR("the MI tree cannot be initialized!\n");
+		goto error;
+	}
+	node = &root->node;
+
+	if (!(crt_node = add_mi_node_child(node, 0, mod_str.s, mod_str.len, 0, 0)) ) {
+		LM_ERR("cannot add the child node to the tree\n");
+		goto error;
+	}
+
+	if ((attr = add_mi_attr(crt_node, MI_DUP_VALUE,
+	    facility_attr.s, facility_attr.len,
+	    facility_str.s, facility_str.len)) == 0) {
+		LM_ERR("cannot add attributes to the node\n");
+		goto error;
+	}
+
+	return root;
+
+error:
+	if (root) {
+		free_mi_tree(root);
+	}
+
+	return NULL;
+}
+
 /**
  * init module function
  */
@@ -144,6 +407,12 @@ static int mod_init(void)
 	int fl;
 	bind_cfgt_t bind_cfgt;
 
+	if (register_mi_mod(exports.name, mi_cmds) != 0)
+	{
+		LM_ERR("failed to register MI commands\n");
+		return -1;
+	}
+
 	if (_dbg_cfgtrace_facility_str!=NULL)
 	{
 		fl = str2facility(_dbg_cfgtrace_facility_str);
@@ -238,6 +507,7 @@ static int child_init(int rank)
 static void mod_destroy(void)
 {
 	dbg_cfg = NULL;
+	dbg_destroy_mod_levels();
 }
 
 /**

+ 155 - 0
modules/debugger/doc/debugger_admin.xml

@@ -616,6 +616,83 @@ P-Hint: My hint
     </section>
 
 
+
+	<section>
+		<title>Exported MI Functions</title>
+
+		<section id="debugger.m.set_dbg_mod_level mod_name level">
+			<title><function moreinfo="none">set_dbg_mod_level mod_name level</function></title>
+			<para>
+				Set the module log level.
+				If module does not exist in kamailio, the entry in the level hashtable is still added for the bogus module.
+			</para>
+			<example>
+				<title><function moreinfo="none">set_dbg_mod_level</function> usage</title>
+				<programlisting format="linespecific">
+...
+$ &ctltool; fifo set_dbg_mod_level core 2
+$ &ctltool; fifo set_dbg_mod_level debugger 3
+...
+				</programlisting>
+			</example>
+		</section>
+
+		<section id="debugger.m.set_dbg_mod_facility mod_name facility">
+			<title><function moreinfo="none">set_dbg_mod_facility mod_name facility</function></title>
+			<para>
+				Set the mod_name log facility.
+				If mod_name does not exist in kamailio, the entry in the facility hashtable is still added for the bogus mod_name.
+			</para>
+			<example>
+				<title><function moreinfo="none">set_dbg_mod_facility</function> usage</title>
+				<programlisting format="linespecific">
+...
+$ &ctltool; fifo set_dbg_mod_facility core LOG_LOCAL1
+$ &ctltool; fifo set_dbg_mod_facility debugger LOG_LOCAL0
+...
+				</programlisting>
+			</example>
+		</section>
+
+		<section id="debugger.m.get_dbg_mod_level mod_name">
+			<title><function moreinfo="none">get_dbg_mod_level mod_name</function></title>
+			<para>
+				Get the mod_name log level.
+				If mod_name does not exist in the level hashtable, returns the config file value.
+			</para>
+			<example>
+				<title><function moreinfo="none">get_dbg_mod_level</function> usage</title>
+				<programlisting format="linespecific">
+...
+$ &ctltool; fifo get_dbg_mod_level core
+$ &ctltool; fifo get_dbg_mod_level debugger
+...
+				</programlisting>
+			</example>
+		</section>
+
+		<section id="debugger.m.get_dbg_mod_facility mod_name">
+			<title><function moreinfo="none">get_dbg_mod_facility mod_name</function></title>
+			<para>
+				Get the mod_name log facility.
+				If mod_name does not exist in the facility hashtable, returns the config file value.
+			</para>
+			<example>
+				<title><function moreinfo="none">get_dbg_mod_facility</function> usage</title>
+				<programlisting format="linespecific">
+...
+$ &ctltool; fifo get_dbg_mod_facility core
+$ &ctltool; fifo get_dbg_mod_facility debugger
+...
+				</programlisting>
+			</example>
+		</section>
+
+	</section>
+
+
+
+
 	<section>
 		<title>Exported RPC Functions</title>
 
@@ -797,7 +874,85 @@ P-Hint: My hint
 		</programlisting>
     </section>
 
+	<section id="dbg.r.set_mod_level">
+		<title>
+			<function moreinfo="none">dbg.set_mod_level</function>
+		</title>
+		<para>
+			Set the module log level.
+			If module does not exist in kamailio, the entry in the level hashtable is still added for the bogus module.
+		</para>
+		<para>
+			Name: <emphasis>dbg.set_mod_level</emphasis>
+		</para>
+		<para>
+			Examples of use with &sercmd;:
+		</para>
+		<programlisting  format="linespecific">
+			dbg.set_mod_level core 1
+		</programlisting>
+	</section>
+
+	<section id="dbg.r.set_mod_facility">
+		<title>
+			<function moreinfo="none">dbg.set_mod_facility</function>
+		</title>
+		<para>
+			Set the module log facility.
+			If module does not exist in kamailio, the entry in the facility hashtable is still added for the bogus module.
+		</para>
+		<para>
+			Name: <emphasis>dbg.set_mod_facility</emphasis>
+		</para>
+		<para>
+			Examples of use with &sercmd;:
+		</para>
+		<programlisting  format="linespecific">
+			dbg.set_mod_facility core LOG_LOCAL1
+		</programlisting>
+	</section>
+
+	<section id="dbg.r.get_mod_level">
+		<title>
+			<function moreinfo="none">dbg.get_mod_level</function>
+		</title>
+		<para>
+			Get the module log level.
+			If module does not exist in kamailio, the entry in the level hashtable is still added for the bogus module.
+		</para>
+		<para>
+			Name: <emphasis>dbg.get_mod_level</emphasis>
+		</para>
+		<para>
+			Examples of use with &sercmd;:
+		</para>
+		<programlisting  format="linespecific">
+			dbg.get_mod_level core
+		</programlisting>
+	</section>
+
+	<section id="dbg.r.get_mod_facility">
+		<title>
+			<function moreinfo="none">dbg.get_mod_facility</function>
+		</title>
+		<para>
+			Get the module log facility.
+			If module does not exist in kamailio, the entry in the facility hashtable is still added for the bogus module.
+		</para>
+		<para>
+			Name: <emphasis>dbg.get_mod_facility</emphasis>
+		</para>
+		<para>
+			Examples of use with &sercmd;:
+		</para>
+		<programlisting  format="linespecific">
+			dbg.get_mod_facility core
+		</programlisting>
+	</section>
+
     </section>
+
+
 	<section>
 		<title>Usage</title>
 		<para>