--- src/include/private/switch_core_pvt.h | 1 + src/include/switch_core.h | 15 +++++++++ src/include/switch_types.h | 5 ++- src/mod/applications/mod_commands/mod_commands.c | 37 ++++++++++++++++++++++ src/mod/applications/mod_dptools/mod_dptools.c | 19 +++++++++++ src/switch_core_session.c | 15 +++++++++ src/switch_log.c | 24 ++++++++++++-- 7 files changed, 112 insertions(+), 4 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 040a6ec..c3b9fc2 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -98,6 +98,7 @@ struct switch_core_session { switch_size_t id; switch_session_flag_t flags; int thread_running; + switch_log_level_t log_level; switch_channel_t *channel; switch_io_event_hooks_t event_hooks; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 7670435..89ffbf3 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -729,6 +729,21 @@ SWITCH_DECLARE(void *) switch_core_session_get_private(_In_ switch_core_session_ SWITCH_DECLARE(switch_status_t) switch_core_session_set_private(_In_ switch_core_session_t *session, _In_ void *private_info); /*! + \brief Set session loglevel + \param session the session + \param loglevel the desired loglevel + \return SWITCH_STATUS_SUCCESS on success +*/ +SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(_In_ switch_core_session_t *session, _In_ switch_log_level_t loglevel); + +/*! + \brief Get session loglevel + \param session the session + \return the loglevel +*/ +SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(_In_ switch_core_session_t *session); + +/*! \brief Add a logical stream to a session \param session the session to add the stream to \param private_info an optional pointer to private data for the new stream diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 4eca73a..415d8cc 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -678,7 +678,8 @@ SWITCH_CHANNEL_ID_EVENT - Write to the event engine as a LOG event typedef enum { SWITCH_CHANNEL_ID_LOG, SWITCH_CHANNEL_ID_LOG_CLEAN, - SWITCH_CHANNEL_ID_EVENT + SWITCH_CHANNEL_ID_EVENT, + SWITCH_SESSION_ID_LOG, } switch_text_channel_t; typedef enum { @@ -692,6 +693,8 @@ typedef uint32_t switch_core_session_message_flag_t; #define SWITCH_CHANNEL_LOG_CLEAN SWITCH_CHANNEL_ID_LOG_CLEAN, __FILE__, __SWITCH_FUNC__, __LINE__, NULL #define SWITCH_CHANNEL_EVENT SWITCH_CHANNEL_ID_EVENT, __FILE__, __SWITCH_FUNC__, __LINE__, NULL +#define SWITCH_SESSION_LOG(session) SWITCH_SESSION_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, (char *)session + /*! \enum switch_channel_state_t \brief Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are often overridden by specific apps) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 677c5fa..52fd2e2 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -1296,6 +1296,41 @@ SWITCH_STANDARD_API(uuid_deflect) return SWITCH_STATUS_SUCCESS; } +#define UUID_LOGLEVEL_SYNTAX "<uuid> <level>" +SWITCH_STANDARD_API(uuid_loglevel) +{ + switch_core_session_t *tsession = NULL; + char *uuid = NULL, *text = NULL; + + if (!switch_strlen_zero(cmd) && (uuid = strdup(cmd))) { + if ((text = strchr(uuid, ' '))) { + *text++ = '\0'; + } + } + + if (switch_strlen_zero(uuid) || switch_strlen_zero(text)) { + stream->write_function(stream, "-USAGE: %s\n", UUID_LOGLEVEL_SYNTAX); + } else { + switch_log_level_t level = switch_log_str2level(text); + + if (level == SWITCH_LOG_INVALID) { + stream->write_function(stream, "-ERR Invalid log level!\n"); + } + else if ((tsession = switch_core_session_locate(uuid))) { + + switch_core_session_set_loglevel(tsession, level); + stream->write_function(stream, "+OK\n"); + switch_core_session_rwunlock(tsession); + } + else { + stream->write_function(stream, "-ERR No Such Channel %s!\n", uuid); + } + } + + switch_safe_free(uuid); + return SWITCH_STATUS_SUCCESS; +} + #define SCHED_TRANSFER_SYNTAX "[+]<time> <uuid> <extension> [<dialplan>] [<context>]" SWITCH_STANDARD_API(sched_transfer_function) { @@ -3148,6 +3183,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "system", "Execute a system command", system_function, SYSTEM_SYNTAX); SWITCH_ADD_API(commands_api_interface, "time_test", "time_test", time_test_function, "<mss>"); + SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX); + /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_NOUNLOAD; } diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 52fc3e9..70d3ebd 100644 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -1648,6 +1648,23 @@ SWITCH_STANDARD_APP(phrase_function) } } +#define SESSION_LOGLEVEL_SYNTAX "<level>" +SWITCH_STANDARD_APP(session_loglevel_function) +{ + if (!switch_strlen_zero(data)) { + switch_log_level_t level = switch_log_str2level(data); + + if (level == SWITCH_LOG_INVALID) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid log level: %s\n", data); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting log level \"%s\" on session\n", switch_log_level2str(level)); + switch_core_session_set_loglevel(session, level); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No log level specified\n"); + } +} + SWITCH_STANDARD_APP(playback_function) { @@ -2428,6 +2445,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load) SWITCH_ADD_APP(app_interface, "wait_for_silence", "wait_for_silence", "wait_for_silence", wait_for_silence_function, WAIT_FOR_SILENCE_SYNTAX, SAF_NONE); + SWITCH_ADD_APP(app_interface, "session_loglevel", "session_loglevel", "session_loglevel", session_loglevel_function, SESSION_LOGLEVEL_SYNTAX, SAF_NONE); + SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt); /* indicate that the module should continue to be loaded */ diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 58f3853..63e80cf 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -221,6 +221,19 @@ SWITCH_DECLARE(int) switch_core_session_get_stream_count(switch_core_session_t * return session->stream_count; } +SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_session_t *session, switch_log_level_t log_level) +{ + switch_assert(session != NULL); + session->log_level = log_level; + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_session_t *session) +{ + switch_assert(session != NULL); + return session->log_level; +} + SWITCH_DECLARE(switch_call_cause_t) switch_core_session_resurrect_channel(const char *endpoint_name, switch_core_session_t **new_session, switch_memory_pool_t **pool, void *data) { @@ -1090,6 +1103,8 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ switch_uuid_format(session->uuid_str, &uuid); } + session->log_level = runtime.hard_log_level; + session->endpoint_interface = endpoint_interface; session->raw_write_frame.data = session->raw_write_buf; session->raw_write_frame.buflen = sizeof(session->raw_write_buf); diff --git a/src/switch_log.c b/src/switch_log.c index 4804f6d..1cea7c4 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -248,12 +248,30 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char switch_time_t now = switch_timestamp_now(); uint32_t len; const char *extra_fmt = "%s [%s] %s:%d %s()%c%s"; + switch_log_level_t level_limit = runtime.hard_log_level; - if (level > runtime.hard_log_level) { - return; + switch_assert(level < SWITCH_LOG_INVALID); + + /* + * Special-case (no pun intended) handling for extensions + */ + switch (channel) { + case SWITCH_SESSION_ID_LOG: + { + switch_core_session_t *session = (switch_core_session_t *)userdata; + switch_assert(session != NULL); + + level_limit = session->log_level; + } + break; + + default: + break; } - switch_assert(level < SWITCH_LOG_INVALID); + if (level > level_limit) { + return; + } va_start(ap, fmt); -- 1.5.6.4