char *odbc_dsn;
char *odbc_user;
char *odbc_pass;
+ uint32_t debug_level;
};
extern struct switch_runtime runtime;
SWITCH_DECLARE(void) switch_cache_db_release_db_handle(switch_cache_db_handle_t **dbh);
SWITCH_DECLARE(void) switch_cache_db_destroy_db_handle(switch_cache_db_handle_t **dbh);
-SWITCH_DECLARE(switch_status_t) switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
- const char *db_name, const char *odbc_user, const char *odbc_pass);
+SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
+ const char *db_name,
+ const char *odbc_user,
+ const char *odbc_pass, const char *file, const char *func, int line);
+#define switch_cache_db_get_db_handle(_a, _b, _c, _d) _switch_cache_db_get_db_handle(_a, _b, _c, _d, __FILE__, __SWITCH_FUNC__, __LINE__)
+
SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, const char *sql, char **err);
SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql_callback(switch_cache_db_handle_t *dbh, const char *sql,
switch_core_db_callback_func_t callback, void *pdata, char **err);
-SWITCH_DECLARE(switch_status_t) switch_core_db_handle(switch_cache_db_handle_t **dbh);
+SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line);
+#define switch_core_db_handle(_a) _switch_core_db_handle(_a, __FILE__, __SWITCH_FUNC__, __LINE__)
+
SWITCH_DECLARE(void) switch_cache_db_test_reactive(switch_cache_db_handle_t *db, const char *test_sql, const char *drop_sql, const char *reactive_sql);
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries);
SWITCH_DECLARE(switch_status_t) switch_cache_db_persistant_execute_trans(switch_cache_db_handle_t *dbh, const char *sql, uint32_t retries);
SWITCH_DECLARE(void) switch_cache_db_detach(void);
+SWITCH_DECLARE(uint32_t) switch_core_debug_level(void);
SWITCH_END_EXTERN_C
#endif
</pre>
*/
typedef enum {
+ SWITCH_LOG_DEBUG10 = 110,
+ SWITCH_LOG_DEBUG9 = 109,
+ SWITCH_LOG_DEBUG8 = 108,
+ SWITCH_LOG_DEBUG7 = 107,
+ SWITCH_LOG_DEBUG6 = 106,
+ SWITCH_LOG_DEBUG5 = 105,
+ SWITCH_LOG_DEBUG4 = 104,
+ SWITCH_LOG_DEBUG3 = 103,
+ SWITCH_LOG_DEBUG2 = 102,
+ SWITCH_LOG_DEBUG1 = 101,
SWITCH_LOG_DEBUG = 7,
SWITCH_LOG_INFO = 6,
SWITCH_LOG_NOTICE = 5,
SCSC_SHUTDOWN_ELEGANT,
SCSC_SHUTDOWN_ASAP,
SCSC_CANCEL_SHUTDOWN,
- SCSC_SEND_SIGHUP
+ SCSC_SEND_SIGHUP,
+ SCSC_DEBUG_LEVEL
} switch_session_ctl_t;
typedef enum {
return SWITCH_STATUS_SUCCESS;
}
-#define CTL_SYNTAX "[send_sighup|hupall|pause|resume|shutdown [cancel|elegant|asap|restart]|sps|sync_clock|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|loglevel [level]]"
+#define CTL_SYNTAX "[send_sighup|hupall|pause|resume|shutdown [cancel|elegant|asap|restart]|sps|sync_clock|reclaim_mem|max_sessions|min_dtmf_duration [num]|max_dtmf_duration [num]|default_dtmf_duration [num]|loglevel [level]|debug_level [level]]"
SWITCH_STANDARD_API(ctl_function)
{
int argc;
switch_core_session_ctl(SCSC_LOGLEVEL, &arg);
stream->write_function(stream, "+OK log level: %s [%d]\n", switch_log_level2str(arg), arg);
}
+ } else if (!strcasecmp(argv[0], "debug_level")) {
+ if (argc > 1) {
+ arg = atoi(argv[1]);
+ } else {
+ arg = -1;
+ }
+
+ switch_core_session_ctl(SCSC_DEBUG_LEVEL, &arg);
+ stream->write_function(stream, "+OK DEBUG level: %d\n", arg);
+
} else if (!strcasecmp(argv[0], "last_sps")) {
switch_core_session_ctl(SCSC_LAST_SPS, &arg);
stream->write_function(stream, "+OK last sessions per second: %d\n", arg);
SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "fsctl", "control messages", ctl_function, CTL_SYNTAX);
switch_console_set_complete("add fsctl hupall");
+ switch_console_set_complete("add fsctl loglevel");
+ switch_console_set_complete("add fsctl debug_level");
switch_console_set_complete("add fsctl pause");
switch_console_set_complete("add fsctl resume");
switch_console_set_complete("add fsctl shutdown");
/*!
\brief Open the default system database
*/
-SWITCH_DECLARE(switch_status_t)switch_core_db_handle(switch_cache_db_handle_t **dbh)
+SWITCH_DECLARE(switch_status_t) _switch_core_db_handle(switch_cache_db_handle_t **dbh, const char *file, const char *func, int line)
{
if (runtime.odbc_dsn && runtime.odbc_user && runtime.odbc_pass) {
- return switch_cache_db_get_db_handle(dbh, runtime.odbc_dsn, runtime.odbc_user, runtime.odbc_pass);
+ return _switch_cache_db_get_db_handle(dbh, runtime.odbc_dsn, runtime.odbc_user, runtime.odbc_pass, file, func, line);
} else {
- return switch_cache_db_get_db_handle(dbh, SWITCH_CORE_DB, NULL, NULL);
+ return _switch_cache_db_get_db_handle(dbh, SWITCH_CORE_DB, NULL, NULL, file, func, line);
}
}
}
#endif
+SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
+{
+ return runtime.debug_level;
+}
+
+
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_t *val)
{
if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
}
*val = runtime.hard_log_level;
break;
+ case SCSC_DEBUG_LEVEL:
+ if (*val > -1) {
+ if (*val > 10) *val = 10;
+ runtime.debug_level = *val;
+ }
+ *val = runtime.debug_level;
+ break;
case SCSC_MAX_SESSIONS:
*val = switch_core_session_limit(*val);
break;
switch_mutex_unlock(dbh_mutex);
}
-SWITCH_DECLARE(switch_status_t)switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
- const char *db_name, const char *odbc_user, const char *odbc_pass)
+SWITCH_DECLARE(switch_status_t)_switch_cache_db_get_db_handle(switch_cache_db_handle_t **dbh,
+ const char *db_name, const char *odbc_user, const char *odbc_pass,
+ const char *file, const char *func, int line)
{
switch_thread_id_t self = switch_thread_self();
char thread_str[CACHE_DB_LEN] = "";
snprintf(thread_str, sizeof(thread_str) - 1, "%s_%lu", db_name, (unsigned long)(intptr_t)self);
switch_mutex_lock(dbh_mutex);
- if (!(new_dbh = switch_core_hash_find(dbh_hash, thread_str))) {
+ if ((new_dbh = switch_core_hash_find(dbh_hash, thread_str))) {
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG1,
+ "Reuse Cached DB handle %s [%s]\n", thread_str, new_dbh->db ? "sqlite" : "ODBC");
+ } else {
switch_hash_index_t *hi;
const void *var;
void *val;
if (!switch_test_flag(new_dbh, CDF_INUSE) && switch_mutex_trylock(new_dbh->mutex) == SWITCH_STATUS_SUCCESS) {
switch_set_flag(new_dbh, CDF_INUSE);
switch_set_string(new_dbh->name, thread_str);
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG1,
+ "Reuse Unused Cached DB handle %s [%s]\n", thread_str, new_dbh->db ? "sqlite" : "ODBC");
break;
}
}
goto end;
}
+ switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_DEBUG1,
+ "Create Cached DB handle %s [%s]\n", thread_str, db ? "sqlite" : "ODBC");
+
switch_core_new_memory_pool(&pool);
new_dbh = switch_core_alloc(pool, sizeof(*new_dbh));
new_dbh->pool = pool;
}
-
-SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, const char *sql, char **err)
+static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t *dbh, const char *sql, char **err)
{
switch_status_t status = SWITCH_STATUS_FALSE;
char *errmsg = NULL;
if (err) *err = NULL;
-
+
if (switch_odbc_available() && dbh->odbc_dbh) {
- switch_odbc_statement_handle_t stmt;
+ switch_odbc_statement_handle_t stmt = NULL;
if ((status = switch_odbc_handle_exec(dbh->odbc_dbh, sql, &stmt)) != SWITCH_ODBC_SUCCESS) {
errmsg = switch_odbc_handle_get_error(dbh->odbc_dbh, stmt);
}
}
}
+ return status;
+}
+
+/**
+ OMFG you cruel bastards. Who chooses 64k as a max buffer len for a sql statement, have you ever heard of transactions?
+ **/
+static switch_status_t switch_cache_db_execute_sql_chunked(switch_cache_db_handle_t *dbh, const char *sql, uint32_t chunk_size, char **err)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+ char *p, *s, *e;
+ int chunk_count;
+ char *dup = NULL;
+ switch_size_t len;
+
+ switch_assert(chunk_size);
+
+ if (err) *err = NULL;
+
+ len = strlen(sql);
+
+ if (chunk_size > len) {
+ return switch_cache_db_execute_sql_real(dbh, sql, err);
+ }
+
+ if (!(chunk_count = strlen(sql) / chunk_size)) {
+ return SWITCH_STATUS_FALSE;
+ }
+
+ dup = strdup(sql);
+
+
+ e = end_of_p(dup);
+ s = dup;
+
+ while(s && s < e) {
+ p = s + chunk_size;
+
+ if (p > e) {
+ p = e;
+ }
+
+ while (p > s && *p != ';') {
+ p--;
+ }
+
+ if (p) {
+ *p = '\0';
+ while(p < e && (*p == '\n' || *p == ' ')) {
+ p++;
+ }
+ }
+
+ status = switch_cache_db_execute_sql_real(dbh, s, err);
+ if (status != SWITCH_STATUS_SUCCESS || (err && *err)) {
+ break;
+ }
+
+ s = p + 1;
+
+ }
+
+ free(dup);
+
+ return status;
+
+}
+
+
+SWITCH_DECLARE(switch_status_t) switch_cache_db_execute_sql(switch_cache_db_handle_t *dbh, const char *sql, char **err)
+{
+ switch_status_t status = SWITCH_STATUS_FALSE;
+
+ if (dbh->db) {
+ status = switch_cache_db_execute_sql_real(dbh, sql, err);
+ } else {
+ status = switch_cache_db_execute_sql_chunked(dbh, (char *)sql, 32000, err);
+ }
+
return status;
}
uint8_t forever = 0;
unsigned begin_retries = 100;
uint8_t again = 0;
-
+
if (!retries) {
forever = 1;
retries = 1000;
}
while (retries > 0) {
- switch_cache_db_execute_sql(dbh, sql, &errmsg);
+
+ switch_cache_db_execute_sql(dbh, sql, &errmsg);
+
+
if (errmsg) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR [%s]\n", errmsg);
free(errmsg);
if (trans && ((itterations == target) || (nothing_in_queue && ++lc >= 500))) {
- if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 100) != SWITCH_STATUS_SUCCESS) {
+ if (switch_cache_db_persistant_execute_trans(sql_manager.event_db, sqlbuf, 1) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "SQL thread unable to commit transaction, records lost!\n");
}
itterations = 0;
const char *extra_fmt = "%s [%s] %s:%d%c%s";
#endif
+ if (level > 100) {
+ if (level - 100 > runtime.debug_level) {
+ return;
+ }
+
+ level = 7;
+ }
+
if (level > runtime.hard_log_level) {
return;
}