From add42a2759e0af8655a16c6cdf7cfb774ab8b957 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Wed, 4 Mar 2009 18:54:43 +0000 Subject: [PATCH] Move sofia logging to the core logging engine, add change sofia loglevel api and add sofia profile xxx siptrace on-off for TPORT_LOG git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@12410 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_log.h | 21 ++++- src/mod/endpoints/mod_sofia/mod_sofia.c | 31 +++++-- src/mod/endpoints/mod_sofia/mod_sofia.h | 21 +++++ src/mod/endpoints/mod_sofia/sofia.c | 109 +++++++++++++++++++----- src/switch_log.c | 16 ++-- 5 files changed, 163 insertions(+), 35 deletions(-) diff --git a/src/include/switch_log.h b/src/include/switch_log.h index b8619223a9..51d156a73a 100644 --- a/src/include/switch_log.h +++ b/src/include/switch_log.h @@ -93,12 +93,31 @@ SWITCH_DECLARE(switch_status_t) switch_log_shutdown(void); \param level the current log level \param fmt desired format \param ... variable args - \note there are channel macros to supply the first 4 parameters + \note there are channel macros to supply the first 4 parameters (SWITCH_CHANNEL_LOG, SWITCH_CHANNEL_LOG_CLEAN, ...) + \see switch_types.h */ SWITCH_DECLARE(void) switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt, ...) PRINTF_FUNCTION(7, 8); +/*! + \brief Write log data to the logging engine + \param channel the log channel to write to + \param file the current file + \param func the current function + \param line the current line + \param userdata ununsed + \param level the current log level + \param fmt desired format + \param ap variable args + \note there are channel macros to supply the first 4 parameters (SWITCH_CHANNEL_LOG, SWITCH_CHANNEL_LOG_CLEAN, ...) + \see switch_types.h +*/ +SWITCH_DECLARE(void) switch_log_vprintf(_In_ switch_text_channel_t channel, _In_z_ const char *file, + _In_z_ const char *func, _In_ int line, + _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, + const char *fmt, va_list ap); + #endif /*! \brief Shut down the logging engine diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 17abbfb6a6..6c824b4726 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -2076,6 +2076,17 @@ static switch_status_t cmd_profile(char **argv, int argc, switch_stream_handle_t } goto done; } + + if (!strcasecmp(argv[1], "siptrace")) { + if (argc > 2) { + int value = switch_true(argv[2]); + nua_set_params(profile->nua, TPTAG_LOG(value), TAG_END()); + stream->write_function(stream, "%s sip debugging on %s", value ? "Enabled" : "Disabled", profile->name); + } else { + stream->write_function(stream, "Usage: sofia profile siptrace \n"); + } + goto done; + } stream->write_function(stream, "-ERR Unknown command!\n"); @@ -2232,7 +2243,8 @@ SWITCH_STANDARD_API(sofia_function) "sofia profile [[start|stop|restart|rescan] [reloadxml]|flush_inbound_reg [] [reboot]|[register|unregister] [|all]|killgw |[stun-auto-disable|stun-enabled] [true|false]]\n" "sofia status profile [ reg ] | [ pres ]\n" "sofia status gateway \n" - "sofia loglevel [0-9]\n" "--------------------------------------------------------------------------------\n"; + "sofia loglevel [0-9]\n" + "--------------------------------------------------------------------------------\n"; if (session) { return SWITCH_STATUS_FALSE; @@ -2260,12 +2272,17 @@ SWITCH_STANDARD_API(sofia_function) } else if (!strcasecmp(argv[0], "xmlstatus")) { func = cmd_xml_status; } else if (!strcasecmp(argv[0], "loglevel")) { - if (argc > 1 && argv[1]) { - int level; - level = atoi(argv[1]); - if (level >= 0 && level <= 9) { - su_log_set_level(NULL, atoi(argv[1])); - stream->write_function(stream, "Sofia-sip log level set to [%d]", level); + if (argc > 2 && argv[2] && switch_is_number(argv[2])) { + int level = atoi(argv[2]); + if (sofia_set_loglevel(argv[1], level) == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "Sofia log level for component [%s] has been set to [%d]", argv[1], level); + } else { + stream->write_function(stream, "%s", usage_string); + } + } else if (argc > 1 && argv[1]) { + int level = sofia_get_loglevel(argv[1]); + if (level >= 0) { + stream->write_function(stream, "Sofia-sip loglevel for [%s] is [%d]", argv[1], level); } else { stream->write_function(stream, "%s", usage_string); } diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 83b19b29bc..a2d3d48ccb 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -104,6 +104,7 @@ typedef struct private_object private_object_t; #include #include #include +#include #include "nua_stack.h" typedef enum { @@ -804,3 +805,23 @@ void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_ha void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); void sofia_sla_handle_sip_r_subscribe(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); + +/* + * Logging control functions + */ + +/*! + * \brief Changes the loglevel of a sofia component + * \param name the sofia component on which to change the loglevel, or "all" to change them all + * \note Valid components are "all", "default" (sofia's default logger), "tport", "iptsec", "nea", "nta", "nth_client", "nth_server", "nua", "soa", "sresolv", "stun" + * \return SWITCH_STATUS_SUCCESS or SWITCH_STATUS_FALSE if the component isnt valid, or the level is out of range + */ +switch_status_t sofia_set_loglevel(const char *name, int level); + +/*! + * \brief Gets the loglevel of a sofia component + * \param name the sofia component on which to change the loglevel + * \note Valid components are "default" (sofia's default logger), "tport", "iptsec", "nea", "nta", "nth_client", "nth_server", "nua", "soa", "sresolv", "stun" + * \return the component's loglevel, or -1 if the component isn't valid + */ +int sofia_get_loglevel(const char *name); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 3f631431b3..77bd21ceba 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -50,6 +50,7 @@ extern su_log_t soa_log[]; extern su_log_t sresolv_log[]; extern su_log_t stun_log[]; + static void set_variable_sip_param(switch_channel_t *channel, char *header_type, sip_param_t const *params); static void sofia_info_send_sipfrag(switch_core_session_t *aleg, switch_core_session_t *bleg); @@ -931,27 +932,81 @@ void launch_sofia_profile_thread(sofia_profile_t *profile) static void logger(void *logarg, char const *fmt, va_list ap) { - char *data = NULL; - - if (fmt) { -#ifdef HAVE_VASPRINTF - int ret; - ret = vasprintf(&data, fmt, ap); - if ((ret == -1) || !data) { - return; - } -#else - data = (char *) malloc(2048); - if (data) { - vsnprintf(data, 2048, fmt, ap); - } else { - return; - } -#endif + if (fmt && ap) { + switch_log_vprintf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, fmt, ap); + } else if (fmt && !ap) { + switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_DEBUG, "%s", fmt); } - if (data) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_CONSOLE, (char *) "%s", data); - free(data); +} + +static switch_status_t sofia_get_logger(const char *name, su_log_t **out) +{ + *out = (void*)0x1; + if (!strcasecmp(name, "tport")) { + *out = tport_log; + } else if (!strcasecmp(name, "iptsec")) { + *out = iptsec_log; + } else if (!strcasecmp(name, "nea")) { + *out = nea_log; + } else if (!strcasecmp(name, "nta")) { + *out = nta_log; + } else if (!strcasecmp(name, "nth_client")) { + *out = nth_client_log; + } else if (!strcasecmp(name, "nth_server")) { + *out = nth_server_log; + } else if (!strcasecmp(name, "nua")) { + *out = nua_log; + } else if (!strcasecmp(name, "sresolv")) { + *out = sresolv_log; + } else if (!strcasecmp(name, "stun")) { + *out = stun_log; + } else if (!strcasecmp(name, "default")){ + *out = NULL; + } + + return (*out != (void*)0x1) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; +} + +switch_status_t sofia_set_loglevel(const char *name, int level) +{ + su_log_t *log = NULL; + switch_status_t status; + + if (level < 0 || level > 9) { + return SWITCH_STATUS_FALSE; + } + + if (!strcasecmp(name, "all")) { + su_log_set_level(NULL, level); + su_log_set_level(tport_log, level); + su_log_set_level(iptsec_log, level); + su_log_set_level(nea_log, level); + su_log_set_level(nta_log, level); + su_log_set_level(nth_client_log, level); + su_log_set_level(nth_server_log, level); + su_log_set_level(nua_log, level); + su_log_set_level(soa_log, level); + su_log_set_level(sresolv_log, level); + su_log_set_level(stun_log, level); + return SWITCH_STATUS_SUCCESS; + } + + if ((status = sofia_get_logger(name, &log)) == SWITCH_STATUS_SUCCESS) { + su_log_set_level(log, level); + } + + return status; +} + +int sofia_get_loglevel(const char *name) +{ + su_log_t *log = NULL; + switch_status_t status; + + if ((status = sofia_get_logger(name, &log)) == SWITCH_STATUS_SUCCESS && log) { /* default logger is NULL */ + return log->log_level; + } else { + return -1; } } @@ -1718,9 +1773,19 @@ switch_status_t config_sofia(int reload, char *profile_name) su_deinit(); return SWITCH_STATUS_FALSE; } - - su_log_redirect(NULL, logger, NULL); + + /* Redirect loggers in sofia */ + su_log_redirect(NULL /* default */, logger, NULL); su_log_redirect(tport_log, logger, NULL); + su_log_redirect(iptsec_log, logger, NULL); + su_log_redirect(nea_log, logger, NULL); + su_log_redirect(nta_log, logger, NULL); + su_log_redirect(nth_client_log, logger, NULL); + su_log_redirect(nth_server_log, logger, NULL); + su_log_redirect(nua_log, logger, NULL); + su_log_redirect(soa_log, logger, NULL); + su_log_redirect(sresolv_log, logger, NULL); + su_log_redirect(stun_log, logger, NULL); } if (!switch_strlen_zero(profile_name) && (profile = sofia_glue_find_profile(profile_name))) { diff --git a/src/switch_log.c b/src/switch_log.c index 6eec4c80ed..9d2fd62d1c 100644 --- a/src/switch_log.c +++ b/src/switch_log.c @@ -243,14 +243,23 @@ static void *SWITCH_THREAD_FUNC log_thread(switch_thread_t *t, void *obj) return NULL; } -#define do_mods (LOG_QUEUE && THREAD_RUNNING) SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char *file, const char *func, int line, const char *userdata, switch_log_level_t level, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + switch_log_vprintf(channel, file, func, line, userdata, level, fmt, ap); + va_end(ap); +} + +#define do_mods (LOG_QUEUE && THREAD_RUNNING) +SWITCH_DECLARE(void) switch_log_vprintf(switch_text_channel_t channel, const char *file, const char *func, int line, + const char *userdata, switch_log_level_t level, const char *fmt, va_list ap) { char *data = NULL; char *new_fmt = NULL; int ret = 0; - va_list ap; FILE *handle; const char *filep = (file ? switch_cut_path(file) : ""); const char *funcp = (func ? func : ""); @@ -265,8 +274,6 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char switch_assert(level < SWITCH_LOG_INVALID); - va_start(ap, fmt); - handle = switch_core_data_channel(channel); if (channel != SWITCH_CHANNEL_ID_LOG_CLEAN) { @@ -285,7 +292,6 @@ SWITCH_DECLARE(void) switch_log_printf(switch_text_channel_t channel, const char } ret = switch_vasprintf(&data, fmt, ap); - va_end(ap); if (ret == -1) { fprintf(stderr, "Memory Error\n");