Skip to content

Commit

Permalink
debugger: add support for static and dynamic, module specific, loggin…
Browse files Browse the repository at this point in the history
…g facility

Added two new debugger params which will support setting per module logging facility.
This is useful when one might want to change logging for a certain module to a different file.
mod_facility_mode (0/1) is used for enabling this. mod_facility (str) is used for
setting the facility.
  • Loading branch information
Stefan Mititelu committed Jun 10, 2015
1 parent d7c0ae4 commit e525043
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 14 deletions.
45 changes: 43 additions & 2 deletions dprint.c
Expand Up @@ -103,12 +103,15 @@ int log_facility_fixup(void *handle, str *gname, str *name, void **val)
*/

/* value for unset local log level */
#define UNSET_LOCAL_DEBUG_LEVEL -255
#define UNSET_LOCAL_DEBUG_LEVEL -255
#define UNSET_LOCAL_DEBUG_FACILITY -255

/* the local debug log level */
static int _local_debug_level = UNSET_LOCAL_DEBUG_LEVEL;
static int _local_debug_facility = UNSET_LOCAL_DEBUG_FACILITY;
/* callback to get per module debug level */
static get_module_debug_level_f _module_debug_level = NULL;
static get_module_debug_facility_f _module_debug_facility = NULL;

/**
* @brief set callback function for per module debug level
Expand All @@ -118,12 +121,17 @@ void set_module_debug_level_cb(get_module_debug_level_f f)
_module_debug_level = f;
}

void set_module_debug_facility_cb(get_module_debug_facility_f f)
{
_module_debug_facility = f;
}

/**
* @brief return the log level - the local one if it set,
* otherwise the global value
*/
int get_debug_level(char *mname, int mnlen) {
int mlevel = L_DBG;
int mlevel;
/*important -- no LOGs inside, because it will loop */
if(unlikely(_module_debug_level!=NULL && mnlen>0)) {
if(_module_debug_level(mname, mnlen, &mlevel)==0) {
Expand All @@ -134,6 +142,23 @@ int get_debug_level(char *mname, int mnlen) {
_local_debug_level : cfg_get(core, core_cfg, debug);
}

/**
* @brief return the log facility - the local one if it set,
* otherwise the global value
*/
int get_debug_facility(char *mname, int mnlen) {
int mfacility;
/*important -- no LOGs inside, because it will loop */
if(unlikely(_module_debug_facility!=NULL && mnlen>0)) {
if(_module_debug_facility(mname, mnlen, &mfacility)==0) {
return mfacility;
}
}
return (_local_debug_facility != UNSET_LOCAL_DEBUG_FACILITY) ?
_local_debug_facility : cfg_get(core, core_cfg, log_facility);
}


/**
* @brief set the local debug log level
*/
Expand All @@ -150,6 +175,22 @@ void reset_local_debug_level(void)
_local_debug_level = UNSET_LOCAL_DEBUG_LEVEL;
}

/**
* @brief set the local debug log facility
*/
void set_local_debug_facility(int facility)
{
_local_debug_facility = facility;
}

/**
* @brief reset the local debug log facility
*/
void reset_local_debug_facility(void)
{
_local_debug_facility = UNSET_LOCAL_DEBUG_FACILITY;
}

typedef struct log_level_color {
char f;
char b;
Expand Down
17 changes: 11 additions & 6 deletions dprint.h
Expand Up @@ -130,18 +130,23 @@ struct log_level_info {

/** @brief per process debug level handling */
int get_debug_level(char *mname, int mnlen);
int get_debug_facility(char *mname, int mnlen);
void set_local_debug_level(int level);
void set_local_debug_facility(int facility);
void reset_local_debug_level(void);
void reset_local_debug_facility(void);
typedef int (*get_module_debug_level_f)(char *mname, int mnlen, int *mlevel);
typedef int (*get_module_debug_facility_f)(char *mname, int mnlen, int *mfacility);
void set_module_debug_level_cb(get_module_debug_level_f f);
void set_module_debug_facility_cb(get_module_debug_facility_f f);

#define is_printable(level) (get_debug_level(LOG_MNAME, LOG_MNAME_LEN)>=(level))
extern struct log_level_info log_level_info[];
extern char *log_name;

#ifndef NO_SIG_DEBUG
/** @brief protection against "simultaneous" printing from signal handlers */
extern volatile int dprint_crit;
extern volatile int dprint_crit;
#endif

int str2facility(char *s);
Expand Down Expand Up @@ -210,7 +215,7 @@ void log_prefix_init(void);
syslog(LOG2SYSLOG_LEVEL(level) | \
(((facility) != DEFAULT_FACILITY) ? \
(facility) : \
cfg_get(core, core_cfg, log_facility)), \
get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
"%s: %s" fmt, \
(lname)?(lname):LOG_LEVEL2NAME(level),\
(prefix), __VA_ARGS__); \
Expand All @@ -227,13 +232,13 @@ void log_prefix_init(void);
syslog(LOG2SYSLOG_LEVEL(L_ALERT) | \
(((facility) != DEFAULT_FACILITY) ? \
(facility) : \
cfg_get(core, core_cfg, log_facility)),\
get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
"%s" fmt, (prefix), __VA_ARGS__); \
else \
syslog(LOG2SYSLOG_LEVEL(L_DBG) | \
(((facility) != DEFAULT_FACILITY) ? \
(facility) : \
cfg_get(core, core_cfg, log_facility)),\
get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
"%s" fmt, (prefix), __VA_ARGS__); \
} \
} \
Expand Down Expand Up @@ -298,7 +303,7 @@ void log_prefix_init(void);
syslog(LOG2SYSLOG_LEVEL(__llevel) |\
(((facility) != DEFAULT_FACILITY) ? \
(facility) : \
cfg_get(core, core_cfg, log_facility)), \
get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
"%.*s%s: %s" fmt,\
log_prefix_val->len, log_prefix_val->s, \
(lname)?(lname):LOG_LEVEL2NAME(__llevel),\
Expand All @@ -307,7 +312,7 @@ void log_prefix_init(void);
syslog(LOG2SYSLOG_LEVEL(__llevel) |\
(((facility) != DEFAULT_FACILITY) ? \
(facility) : \
cfg_get(core, core_cfg, log_facility)), \
get_debug_facility(LOG_MNAME, LOG_MNAME_LEN)), \
"%s: %s" fmt,\
(lname)?(lname):LOG_LEVEL2NAME(__llevel),\
(prefix) , ## args); \
Expand Down
176 changes: 173 additions & 3 deletions modules/debugger/debugger_api.c
Expand Up @@ -985,12 +985,44 @@ static void dbg_rpc_mod_level(rpc_t* rpc, void* ctx){

if(dbg_set_mod_debug_level(value.s, value.len, &l)<0)
{
rpc->fault(ctx, 500, "cannot store parameter\n");
rpc->fault(ctx, 500, "cannot store parameter");
return;
}
rpc->add(ctx, "s", "200 ok");
}

/**
*
*/
static const char* dbg_rpc_mod_facility_doc[2] = {
"Specify module log facility",
0
};

static void dbg_rpc_mod_facility(rpc_t* rpc, void* ctx) {
int fl;
str value = {0, 0};
str facility = {0, 0};

if (rpc->scan(ctx, "SS", &value, &facility) < 1)
{
rpc->fault(ctx, 500, "invalid parameters");
return;
}

if ((fl = str2facility(facility.s)) == -1) {
rpc->fault(ctx, 500, "facility not found");
return;
}

if(dbg_set_mod_debug_facility(value.s, value.len, &fl) < 0)
{
rpc->fault(ctx, 500, "cannot store parameter");
return;
}
rpc->add(ctx, "s", "200 ok");
}

/**
*
*/
Expand Down Expand Up @@ -1032,6 +1064,7 @@ rpc_export_t dbg_rpc[] = {
{"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.reset_msgid", dbg_rpc_reset_msgid, dbg_rpc_reset_msgid_doc, 0},
{0, 0, 0, 0}
};
Expand All @@ -1056,10 +1089,19 @@ typedef struct _dbg_mod_level {
struct _dbg_mod_level *next;
} dbg_mod_level_t;

typedef struct _dbg_mod_facility {
str name;
unsigned int hashid;
int facility;
struct _dbg_mod_facility *next;
} dbg_mod_facility_t;

typedef struct _dbg_mod_slot
{
dbg_mod_level_t *first;
gen_lock_t lock;
dbg_mod_facility_t *first_ft;
gen_lock_t lock_ft;
} dbg_mod_slot_t;

static dbg_mod_slot_t *_dbg_mod_table = NULL;
Expand All @@ -1086,13 +1128,15 @@ int dbg_init_mod_levels(int dbg_mod_hash_size)

for(i=0; i<_dbg_mod_table_size; i++)
{
if(lock_init(&_dbg_mod_table[i].lock)==0)
if(lock_init(&_dbg_mod_table[i].lock)==0 ||
lock_init(&_dbg_mod_table[i].lock_ft)==0)
{
LM_ERR("cannot initialize lock[%d]\n", i);
i--;
while(i>=0)
{
lock_destroy(&_dbg_mod_table[i].lock);
lock_destroy(&_dbg_mod_table[i].lock_ft);
i--;
}
shm_free(_dbg_mod_table);
Expand Down Expand Up @@ -1209,6 +1253,82 @@ int dbg_set_mod_debug_level(char *mname, int mnlen, int *mlevel)

}

int dbg_set_mod_debug_facility(char *mname, int mnlen, int *mfacility)
{
unsigned int idx;
unsigned int hid;
dbg_mod_facility_t *it;
dbg_mod_facility_t *itp;
dbg_mod_facility_t *itn;

if(_dbg_mod_table==NULL)
return -1;

hid = dbg_compute_hash(mname, mnlen);
idx = hid&(_dbg_mod_table_size-1);

lock_get(&_dbg_mod_table[idx].lock_ft);
it = _dbg_mod_table[idx].first_ft;
itp = NULL;
while(it!=NULL && it->hashid < hid) {
itp = it;
it = it->next;
}
while(it!=NULL && it->hashid==hid)
{
if(mnlen==it->name.len
&& strncmp(mname, it->name.s, mnlen)==0)
{
/* found */
if(mfacility==NULL) {
/* remove */
if(itp!=NULL) {
itp->next = it->next;
} else {
_dbg_mod_table[idx].first_ft = it->next;
}
shm_free(it);
} else {
/* set */
it->facility = *mfacility;
}
lock_release(&_dbg_mod_table[idx].lock_ft);
return 0;
}
itp = it;
it = it->next;
}
/* not found - add */
if(mfacility==NULL) {
lock_release(&_dbg_mod_table[idx].lock_ft);
return 0;
}
itn = (dbg_mod_facility_t*)shm_malloc(sizeof(dbg_mod_facility_t) + (mnlen+1)*sizeof(char));
if(itn==NULL) {
LM_ERR("no more shm\n");
lock_release(&_dbg_mod_table[idx].lock_ft);
return -1;
}
memset(itn, 0, sizeof(dbg_mod_facility_t) + (mnlen+1)*sizeof(char));
itn->facility = *mfacility;
itn->hashid = hid;
itn->name.s = (char*)(itn) + sizeof(dbg_mod_facility_t);
itn->name.len = mnlen;
strncpy(itn->name.s, mname, mnlen);
itn->name.s[itn->name.len] = '\0';

if(itp==NULL) {
itn->next = _dbg_mod_table[idx].first_ft;
_dbg_mod_table[idx].first_ft = itn;
} else {
itn->next = itp->next;
itp->next = itn;
}
lock_release(&_dbg_mod_table[idx].lock_ft);
return 0;

}

static int _dbg_get_mod_debug_level = 0;
int dbg_get_mod_debug_level(char *mname, int mnlen, int *mlevel)
{
Expand Down Expand Up @@ -1252,6 +1372,49 @@ int dbg_get_mod_debug_level(char *mname, int mnlen, int *mlevel)
return -1;
}

static int _dbg_get_mod_debug_facility = 0;
int dbg_get_mod_debug_facility(char *mname, int mnlen, int *mfacility)
{
unsigned int idx;
unsigned int hid;
dbg_mod_facility_t *it;
/* no LOG*() usage in this function and those executed insite it
* - use fprintf(stderr, ...) if need for troubleshooting
* - it will loop otherwise */
if(_dbg_mod_table==NULL)
return -1;

if(cfg_get(dbg, dbg_cfg, mod_facility_mode)==0)
return -1;

if(_dbg_get_mod_debug_facility!=0)
return -1;
_dbg_get_mod_debug_facility = 1;

hid = dbg_compute_hash(mname, mnlen);
idx = hid&(_dbg_mod_table_size-1);
lock_get(&_dbg_mod_table[idx].lock_ft);
it = _dbg_mod_table[idx].first_ft;
while(it!=NULL && it->hashid < hid)
it = it->next;
while(it!=NULL && it->hashid == hid)
{
if(mnlen==it->name.len
&& strncmp(mname, it->name.s, mnlen)==0)
{
/* found */
*mfacility = it->facility;
lock_release(&_dbg_mod_table[idx].lock_ft);
_dbg_get_mod_debug_facility = 0;
return 0;
}
it = it->next;
}
lock_release(&_dbg_mod_table[idx].lock_ft);
_dbg_get_mod_debug_facility = 0;
return -1;
}

/**
*
*/
Expand All @@ -1262,6 +1425,13 @@ void dbg_enable_mod_levels(void)
set_module_debug_level_cb(dbg_get_mod_debug_level);
}

void dbg_enable_mod_facilities(void)
{
if(_dbg_mod_table==NULL)
return;
set_module_debug_facility_cb(dbg_get_mod_debug_facility);
}

#define DBG_PVCACHE_SIZE 32

typedef struct _dbg_pvcache {
Expand Down Expand Up @@ -1423,7 +1593,7 @@ void dbg_enable_log_assign(void)
set_log_assign_action_cb(dbg_log_assign);
}

int dbg_level_mode_fixup(void *temp_handle,
int dbg_mode_fixup(void *temp_handle,
str *group_name, str *var_name, void **value){
if(_dbg_mod_table==NULL)
{
Expand Down

0 comments on commit e525043

Please sign in to comment.