diff --git a/README.md b/README.md index 43158c59c..9c9bfe4c5 100644 --- a/README.md +++ b/README.md @@ -838,6 +838,10 @@ Optionally included keys are: Identical to setting `generate RTCP = on`. + - `debug` or `debugging` + + Enabled full debug logging for this call, regardless of global log level settings. + * `generate RTCP` Contains a string, either `on` or `off`. If enabled for a call, diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 9ffd0eaf5..0f80be1b6 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -836,6 +836,12 @@ static void call_ng_flags_flags(struct sdp_ng_flags *out, str *s, void *dummy) { case CSH_LOOKUP("record-call"): out->record_call = 1; break; + case CSH_LOOKUP("debug"): + out->debug = 1; + break; + case CSH_LOOKUP("debugging"): + out->debug = 1; + break; case CSH_LOOKUP("no-rtcp-attribute"): out->no_rtcp_attr = 1; break; @@ -1384,6 +1390,9 @@ static const char *call_offer_answer_ng(struct ng_buffer *ngbuf, bencode_item_t if (!call) goto out; + if (flags.debug) + call->debug = 1; + if (rtpe_config.active_switchover && IS_FOREIGN_CALL(call)) call_make_own_foreign(call, 0); diff --git a/daemon/cli.c b/daemon/cli.c index 483c7cbeb..184be70e3 100644 --- a/daemon/cli.c +++ b/daemon/cli.c @@ -47,6 +47,7 @@ static void cli_incoming_ksrm(str *instr, struct cli_writer *cw); static void cli_incoming_kslist(str *instr, struct cli_writer *cw); static void cli_incoming_active(str *instr, struct cli_writer *cw); static void cli_incoming_standby(str *instr, struct cli_writer *cw); +static void cli_incoming_debug(str *instr, struct cli_writer *cw); static void cli_incoming_set_maxopenfiles(str *instr, struct cli_writer *cw); static void cli_incoming_set_maxsessions(str *instr, struct cli_writer *cw); @@ -106,6 +107,7 @@ static const cli_handler_t cli_top_handlers[] = { { "kslist", cli_incoming_kslist }, { "active", cli_incoming_active }, { "standby", cli_incoming_standby }, + { "debug", cli_incoming_debug }, { NULL, }, }; static const cli_handler_t cli_set_handlers[] = { @@ -543,7 +545,7 @@ static void cli_incoming_list_callid(str *instr, struct cli_writer *cw) { c = call_get(instr); if (!c) { - cw->cw_printf(cw, "\nCall Id not found (%s).\n\n", instr->s); + cw->cw_printf(cw, "\nCall ID not found (" STR_FORMAT ").\n\n", STR_FMT(instr)); return; } @@ -1088,6 +1090,49 @@ static void cli_incoming_standby(str *instr, struct cli_writer *cw) { cli_incoming_active_standby(cw, 1); } +static void cli_incoming_debug(str *instr, struct cli_writer *cw) { + if (str_shift(instr, 1)) { + cw->cw_printf(cw, "No call ID specified\n"); + return; + } + + str callid = STR_NULL; + str_token_sep(&callid, instr, ' '); + + if (!callid.len) { + cw->cw_printf(cw, "No call ID specified\n"); + return; + } + + int flag = 1; + + if (instr->len) { + if (!str_cmp(instr, "on") || !str_cmp(instr, "enable")) + ; + else if (!str_cmp(instr, "off") || !str_cmp(instr, "disable")) + flag = 0; + else { + cw->cw_printf(cw, "Invalid on/off flag ('" STR_FORMAT "') specified\n", STR_FMT(instr)); + return; + } + } + + struct call *c = call_get(&callid); + + if (!c) { + cw->cw_printf(cw, "Call ID '" STR_FORMAT "' not found\n", STR_FMT(&callid)); + return; + } + + c->debug = flag; + + cw->cw_printf(cw, "%s debugging for call '" STR_FORMAT "'\n", flag ? "Enabled" : "Disabled", + STR_FMT(&callid)); + + rwlock_unlock_w(&c->master_lock); + obj_put(c); +} + static void cli_incoming(struct streambuf_stream *s) { ilogs(control, LOG_INFO, "New cli connection from %s", s->addr); } diff --git a/daemon/log.c b/daemon/log.c index b2bf4d802..b753ecba2 100644 --- a/daemon/log.c +++ b/daemon/log.c @@ -135,3 +135,22 @@ void dtmflog(GString *s) { void rtcplog(const char* cdrbuffer) { syslog(LOG_INFO | _log_facility_rtcp, "%s", cdrbuffer); } + +int get_local_log_level(unsigned int subsystem_idx) { + switch (log_info.e) { + case LOG_INFO_CALL: + if (log_info.u.call->debug) + return 8; + return -1; + case LOG_INFO_STREAM_FD: + if (log_info.u.stream_fd->call && log_info.u.stream_fd->call->debug) + return 8; + return -1; + case LOG_INFO_ICE_AGENT: + if (log_info.u.ice_agent->call && log_info.u.ice_agent->call->debug) + return 8; + return -1; + default: + return -1; + } +} diff --git a/include/call.h b/include/call.h index a0c4f5aac..e62f29ae2 100644 --- a/include/call.h +++ b/include/call.h @@ -436,6 +436,7 @@ struct call { unsigned int drop_traffic:1; unsigned int foreign_call:1; // created_via_redis_notify call unsigned int disable_jb:1; + unsigned int debug:1; }; diff --git a/include/call_interfaces.h b/include/call_interfaces.h index d654e8815..5bbc32a89 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -97,6 +97,7 @@ struct sdp_ng_flags { all:1, fragment:1, record_call:1, + debug:1, loop_protect:1, original_sendrecv:1, asymmetric_codecs:1, diff --git a/lib/loglib.h b/lib/loglib.h index 3079273cb..c57c373f7 100644 --- a/lib/loglib.h +++ b/lib/loglib.h @@ -13,6 +13,8 @@ extern int ilog_facility; extern unsigned int max_log_line_length; +extern int get_local_log_level(unsigned int); + typedef void write_log_t(int facility_priority, const char *format, ...) __attribute__ ((format (printf, 2, 3))); extern write_log_t *write_log; @@ -46,7 +48,7 @@ extern const char * const log_level_descriptions[]; #ifndef __DEBUG #define ilogsn(system, prio, fmt, ...) \ do { \ - int __loglevel = __get_log_level(system); \ + int __loglevel = __get_log_level(system); \ if (LOG_LEVEL_MASK((prio)) > LOG_LEVEL_MASK(__loglevel)) \ break; \ if ((__loglevel & LOG_FLAG_RESTORE) && !((prio) & LOG_FLAG_RESTORE)) \ @@ -67,6 +69,9 @@ INLINE int __get_log_level(unsigned int idx) { return 8; if (idx >= MAX_LOG_LEVELS) return 8; + int local_log_level = get_local_log_level(idx); + if (local_log_level >= 0) + return local_log_level; return g_atomic_int_get(&rtpe_common_config_ptr->log_levels[idx]); } #define get_log_level(system) __get_log_level(log_level_index_ ## system) diff --git a/recording-daemon/log.c b/recording-daemon/log.c index e4fd2889f..0597e8137 100644 --- a/recording-daemon/log.c +++ b/recording-daemon/log.c @@ -26,3 +26,7 @@ void __ilog(int prio, const char *fmt, ...) { __vpilog(prio, prefix, fmt, ap); va_end(ap); } + +int get_local_log_level(unsigned int subsystem_idx) { + return -1; +} diff --git a/t/aead-aes-crypt.c b/t/aead-aes-crypt.c index 046e45b1d..609be710c 100644 --- a/t/aead-aes-crypt.c +++ b/t/aead-aes-crypt.c @@ -225,3 +225,7 @@ int main(void) crypto_cleanup_session_key(&ctx); } + +int get_local_log_level(unsigned int u) { + return -1; +} diff --git a/t/aes-crypt.c b/t/aes-crypt.c index 3e95a4204..1422c97ef 100644 --- a/t/aes-crypt.c +++ b/t/aes-crypt.c @@ -298,3 +298,7 @@ int main(int argc, char** argv) { crypto_cleanup_session_key(&ctx); } + +int get_local_log_level(unsigned int u) { + return -1; +} diff --git a/t/test-const_str_hash.c b/t/test-const_str_hash.c index 2ff732c57..044bf2c35 100644 --- a/t/test-const_str_hash.c +++ b/t/test-const_str_hash.c @@ -33,3 +33,7 @@ int main(void) { test("doesn't exist", 0); return 0; } + +int get_local_log_level(unsigned int u) { + return -1; +} diff --git a/t/test-payload-tracker.c b/t/test-payload-tracker.c index 48f25b068..b5575e499 100644 --- a/t/test-payload-tracker.c +++ b/t/test-payload-tracker.c @@ -98,3 +98,7 @@ int main(void) { return 0; } + +int get_local_log_level(unsigned int u) { + return -1; +} diff --git a/t/test-transcode.c b/t/test-transcode.c index d3b49b248..9839cd587 100644 --- a/t/test-transcode.c +++ b/t/test-transcode.c @@ -1731,3 +1731,7 @@ int main(void) { return 0; } + +int get_local_log_level(unsigned int u) { + return -1; +} diff --git a/utils/rtpengine-ctl b/utils/rtpengine-ctl index ed0fc5b74..0b07eea5d 100755 --- a/utils/rtpengine-ctl +++ b/utils/rtpengine-ctl @@ -159,6 +159,8 @@ sub showusage { print " active : set all running sessions to 'owned'\n"; print " standby : set all running sessions to 'foreign'\n"; print "\n"; + print " debug : set debugging flag for given call\n"; + print "\n"; print "\n"; print " Return Value:\n"; print " 0 on success with output from server side, other values for failure.\n";