uint32_t read_frame_count;
uint32_t track_duration;
uint32_t track_id;
+ switch_log_level_t loglevel;
};
struct switch_media_bug {
SWITCH_DECLARE(int) switch_channel_test_app_flag(switch_channel_t *channel, uint32_t flags);
SWITCH_DECLARE(void) switch_channel_set_hangup_time(switch_channel_t *channel);
SWITCH_DECLARE(switch_call_direction_t) switch_channel_direction(switch_channel_t *channel);
+SWITCH_DECLARE(switch_core_session_t*) switch_channel_get_session(switch_channel_t *channel);
/** @} */
*/
SWITCH_DECLARE(char *) switch_core_session_get_uuid(_In_ switch_core_session_t *session);
+
+/*!
+ \brief Sets the log level for a session
+ \param session the session to set the log level on
+ \return SWITCH_STATUS_SUCCESS
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_session_t *session, switch_log_level_t loglevel);
+
+
+/*!
+ \brief Get the log level for a session
+ \param session the session to get the log level from
+ \return the log level
+*/
+SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_session_t *session);
+
/*!
\brief Retrieve the unique identifier from the core
\return a string representing the uuid
typedef enum {
SWITCH_CHANNEL_ID_LOG,
SWITCH_CHANNEL_ID_LOG_CLEAN,
- SWITCH_CHANNEL_ID_EVENT
+ SWITCH_CHANNEL_ID_EVENT,
+ SWITCH_CHANNEL_ID_SESSION
} switch_text_channel_t;
typedef enum {
#define SWITCH_CHANNEL_LOG SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, NULL
#define SWITCH_CHANNEL_LOG_CLEAN SWITCH_CHANNEL_ID_LOG_CLEAN, __FILE__, __SWITCH_FUNC__, __LINE__, NULL
-#define SWITCH_CHANNEL_SESSION_LOG_CLEAN(x) SWITCH_CHANNEL_ID_LOG_CLEAN, __FILE__, __SWITCH_FUNC__, __LINE__, ((x) ? switch_core_session_get_uuid(x) : NULL)
+#define SWITCH_CHANNEL_SESSION_LOG_CLEAN(x) SWITCH_CHANNEL_ID_LOG_CLEAN, __FILE__, __SWITCH_FUNC__, __LINE__, switch_core_session_get_uuid((x))
#define SWITCH_CHANNEL_EVENT SWITCH_CHANNEL_ID_EVENT, __FILE__, __SWITCH_FUNC__, __LINE__, NULL
-#define SWITCH_CHANNEL_SESSION_LOG(x) SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, ((x) ? switch_core_session_get_uuid(x) : NULL)
-#define SWITCH_CHANNEL_CHANNEL_LOG(x) SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, ((x) ? switch_channel_get_uuid(x) : NULL)
-#define SWITCH_CHANNEL_UUID_LOG(x) SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, x
+#define SWITCH_CHANNEL_SESSION_LOG(x) SWITCH_CHANNEL_ID_SESSION, __FILE__, __SWITCH_FUNC__, __LINE__, (const char*)(x)
+#define SWITCH_CHANNEL_CHANNEL_LOG(x) SWITCH_CHANNEL_ID_SESSION, __FILE__, __SWITCH_FUNC__, __LINE__, (const char*)switch_channel_get_session(x)
+#define SWITCH_CHANNEL_UUID_LOG(x) SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, (x)
/*!
\enum switch_channel_state_t
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 (!zstr(cmd) && (uuid = strdup(cmd))) {
+ if ((text = strchr(uuid, ' '))) {
+ *text++ = '\0';
+ }
+ }
+
+ if (zstr(uuid) || zstr(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;
+}
+
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown)
{
int x;
SWITCH_ADD_API(commands_api_interface, "uuid_getvar", "uuid_getvar", uuid_getvar_function, GETVAR_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
+ SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_preprocess", "Pre-process Channel", preprocess_function, PREPROCESS_SYNTAX);
switch_console_set_complete("add fsctl default_dtmf_duration");
switch_console_set_complete("add fsctl hupall");
switch_console_set_complete("add fsctl loglevel");
+ switch_console_set_complete("add fsctl loglevel console");
+ switch_console_set_complete("add fsctl loglevel alert");
+ switch_console_set_complete("add fsctl loglevel crit");
+ switch_console_set_complete("add fsctl loglevel err");
+ switch_console_set_complete("add fsctl loglevel warning");
+ switch_console_set_complete("add fsctl loglevel notice");
+ switch_console_set_complete("add fsctl loglevel info");
+ switch_console_set_complete("add fsctl loglevel debug");
switch_console_set_complete("add fsctl max_dtmf_duration");
switch_console_set_complete("add fsctl max_sessions");
switch_console_set_complete("add fsctl min_dtmf_duration");
switch_console_set_complete("add uuid_getvar ::console::list_uuid");
switch_console_set_complete("add uuid_hold ::console::list_uuid");
switch_console_set_complete("add uuid_kill ::console::list_uuid");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid console");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid alert");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid crit");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid err");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid warning");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid notice");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid info");
+ switch_console_set_complete("add uuid_loglevel ::console::list_uuid debug");
switch_console_set_complete("add uuid_media ::console::list_uuid");
switch_console_set_complete("add uuid_park ::console::list_uuid");
switch_console_set_complete("add uuid_preprocess ::console::list_uuid");
return SWITCH_STATUS_SUCCESS;
}
+
+#define SESSION_LOGLEVEL_SYNTAX "<level>"
+SWITCH_STANDARD_APP(session_loglevel_function)
+{
+ if (!zstr(data)) {
+ switch_log_level_t level = switch_log_str2level(data);
+
+ if (level == SWITCH_LOG_INVALID) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid log level: %s\n", data);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), 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_SESSION_LOG(session), SWITCH_LOG_ERROR, "No log level specified\n");
+ }
+}
+
#define SPEAK_DESC "Speak text to a channel via the tts interface"
#define DISPLACE_DESC "Displace audio from a file to the channels input"
#define SESS_REC_DESC "Starts a background recording of the entire session"
SWITCH_ADD_APP(app_interface, "say", "say", "say", say_function, SAY_SYNTAX, SAF_NONE);
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_SUPPORT_NOMEDIA);
SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt);
return status;
}
+SWITCH_DECLARE(switch_core_session_t*) switch_channel_get_session(switch_channel_t *channel)
+{
+ switch_assert(channel);
+ return channel->session;
+}
+
SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(switch_channel_t *channel)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
return status;
}
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_session_t *session, switch_log_level_t loglevel)
+{
+ switch_assert(session != NULL);
+ session->loglevel = loglevel;
+ 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->loglevel;
+}
+
/* For Emacs:
* Local Variables:
* mode:c
#else
const char *extra_fmt = "%s [%s] %s:%d%c%s";
#endif
+ switch_log_level_t limit_level = runtime.hard_log_level;
+
+ if (channel == SWITCH_CHANNEL_ID_SESSION && userdata) {
+ switch_core_session_t *session = (switch_core_session_t*)userdata;
+ if (limit_level < session->loglevel) {
+ limit_level = session->loglevel;
+ }
+ }
if (level > 100) {
if ((uint32_t)(level - 100) > runtime.debug_level) {
level = 7;
}
- if (level > runtime.hard_log_level) {
+ if (level > limit_level) {
return;
}
node->content = content;
node->timestamp = now;
node->channel = channel;
- node->userdata = !zstr(userdata) ? strdup(userdata) : NULL;
+ if (channel == SWITCH_CHANNEL_ID_SESSION) {
+ node->userdata = userdata ? strdup(switch_core_session_get_uuid((switch_core_session_t*)userdata)) : NULL;
+ } else {
+ node->userdata = !zstr(userdata) ? strdup(userdata) : NULL;
+ }
if (switch_queue_trypush(LOG_QUEUE, node) != SWITCH_STATUS_SUCCESS) {
switch_log_node_free(&node);