mod_cdr_pg_csv: make disk spool format user-selectable
This commit is contained in:
parent
7b28994121
commit
a3d66bb4f0
|
@ -9,6 +9,8 @@
|
||||||
<param name="default-template" value="example"/>
|
<param name="default-template" value="example"/>
|
||||||
<!-- 'cdr-pg-csv' will always be appended to log-base -->
|
<!-- 'cdr-pg-csv' will always be appended to log-base -->
|
||||||
<!--<param name="log-base" value="/var/log"/>-->
|
<!--<param name="log-base" value="/var/log"/>-->
|
||||||
|
<!-- Disk spool format if DB connection/insert fails - csv (default) or sql -->
|
||||||
|
<param name="spool-format" value="csv"/>
|
||||||
<param name="rotate-on-hup" value="true"/>
|
<param name="rotate-on-hup" value="true"/>
|
||||||
<!-- This is like the info app but after the call is hung up -->
|
<!-- This is like the info app but after the call is hung up -->
|
||||||
<!--<param name="debug" value="true"/>-->
|
<!--<param name="debug" value="true"/>-->
|
||||||
|
|
|
@ -67,6 +67,7 @@ static struct {
|
||||||
cdr_leg_t legs;
|
cdr_leg_t legs;
|
||||||
char *db_info;
|
char *db_info;
|
||||||
char *db_table;
|
char *db_table;
|
||||||
|
char *spool_format;
|
||||||
PGconn *db_connection;
|
PGconn *db_connection;
|
||||||
int db_online;
|
int db_online;
|
||||||
switch_mutex_t *db_mutex;
|
switch_mutex_t *db_mutex;
|
||||||
|
@ -141,6 +142,7 @@ static void do_rotate(cdr_fd_t *fd)
|
||||||
static void write_cdr(const char *path, const char *log_line)
|
static void write_cdr(const char *path, const char *log_line)
|
||||||
{
|
{
|
||||||
cdr_fd_t *fd = NULL;
|
cdr_fd_t *fd = NULL;
|
||||||
|
char *log_line_lf = NULL;
|
||||||
unsigned int bytes_in, bytes_out;
|
unsigned int bytes_in, bytes_out;
|
||||||
int loops = 0;
|
int loops = 0;
|
||||||
|
|
||||||
|
@ -154,8 +156,17 @@ static void write_cdr(const char *path, const char *log_line)
|
||||||
switch_core_hash_insert(globals.fd_hash, path, fd);
|
switch_core_hash_insert(globals.fd_hash, path, fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (end_of(log_line) != '\n') {
|
||||||
|
size_t len = strlen(log_line) + 2;
|
||||||
|
log_line_lf = switch_core_alloc(globals.pool, len);
|
||||||
|
switch_snprintf(log_line_lf, len, "%s\n", log_line);
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Adding LF to log_line.\n");
|
||||||
|
} else {
|
||||||
|
log_line_lf = switch_core_strdup(globals.pool, log_line);
|
||||||
|
}
|
||||||
|
|
||||||
switch_mutex_lock(fd->mutex);
|
switch_mutex_lock(fd->mutex);
|
||||||
bytes_out = (unsigned) strlen(log_line);
|
bytes_out = (unsigned) strlen(log_line_lf);
|
||||||
|
|
||||||
if (fd->fd < 0) {
|
if (fd->fd < 0) {
|
||||||
do_reopen(fd);
|
do_reopen(fd);
|
||||||
|
@ -169,7 +180,7 @@ static void write_cdr(const char *path, const char *log_line)
|
||||||
do_rotate(fd);
|
do_rotate(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((bytes_in = write(fd->fd, log_line, bytes_out)) != bytes_out && ++loops < 10) {
|
while ((bytes_in = write(fd->fd, log_line_lf, bytes_out)) != bytes_out && ++loops < 10) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write error to file %s %d/%d\n", path, (int) bytes_in, (int) bytes_out);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write error to file %s %d/%d\n", path, (int) bytes_in, (int) bytes_out);
|
||||||
do_rotate(fd);
|
do_rotate(fd);
|
||||||
switch_yield(250000);
|
switch_yield(250000);
|
||||||
|
@ -184,7 +195,7 @@ static void write_cdr(const char *path, const char *log_line)
|
||||||
switch_mutex_unlock(fd->mutex);
|
switch_mutex_unlock(fd->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t save_cdr(const char * const template, const char * const cdr, const char * const log_dir)
|
static switch_status_t save_cdr(const char * const template, const char * const cdr)
|
||||||
{
|
{
|
||||||
char *columns, *values;
|
char *columns, *values;
|
||||||
char *p, *q;
|
char *p, *q;
|
||||||
|
@ -214,7 +225,7 @@ static switch_status_t save_cdr(const char * const template, const char * const
|
||||||
/*
|
/*
|
||||||
* In the expanded vars, replace double quotes (") with single quotes (')
|
* In the expanded vars, replace double quotes (") with single quotes (')
|
||||||
* for correct PostgreSQL syntax, and replace semi-colon with space to
|
* for correct PostgreSQL syntax, and replace semi-colon with space to
|
||||||
* prevent SQL injection attacks.
|
* prevent SQL injection attacks
|
||||||
*/
|
*/
|
||||||
values = strdup(cdr);
|
values = strdup(cdr);
|
||||||
for (p = values; *p; ++p) {
|
for (p = values; *p; ++p) {
|
||||||
|
@ -309,9 +320,7 @@ static switch_status_t save_cdr(const char * const template, const char * const
|
||||||
values = nullValues;
|
values = nullValues;
|
||||||
free(tp);
|
free(tp);
|
||||||
|
|
||||||
//----------------------------- END_OF_PATCH -------------------------------
|
sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);", globals.db_table, columns, values);
|
||||||
|
|
||||||
sql = switch_mprintf("INSERT INTO %s (%s) VALUES (%s);\n", globals.db_table, columns, values);
|
|
||||||
assert(sql);
|
assert(sql);
|
||||||
free(columns);
|
free(columns);
|
||||||
free(values);
|
free(values);
|
||||||
|
@ -355,22 +364,27 @@ static switch_status_t save_cdr(const char * const template, const char * const
|
||||||
switch_mutex_unlock(globals.db_mutex);
|
switch_mutex_unlock(globals.db_mutex);
|
||||||
|
|
||||||
/* SQL INSERT failed for whatever reason. Spool the attempted query to disk */
|
/* SQL INSERT failed for whatever reason. Spool the attempted query to disk */
|
||||||
path = switch_mprintf("%s%scdr-spool.sql", log_dir, SWITCH_PATH_SEPARATOR);
|
if (!strcasecmp(globals.spool_format, "sql")) {
|
||||||
|
path = switch_mprintf("%s%scdr-spool.sql", globals.log_dir, SWITCH_PATH_SEPARATOR);
|
||||||
assert(path);
|
assert(path);
|
||||||
write_cdr(path, sql);
|
write_cdr(path, sql);
|
||||||
|
} else {
|
||||||
|
path = switch_mprintf("%s%scdr-spool.csv", globals.log_dir, SWITCH_PATH_SEPARATOR);
|
||||||
|
assert(path);
|
||||||
|
write_cdr(path, cdr);
|
||||||
|
}
|
||||||
|
|
||||||
free(path);
|
free(path);
|
||||||
free(sql);
|
free(sql);
|
||||||
|
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static switch_status_t my_on_reporting(switch_core_session_t *session)
|
static switch_status_t my_on_reporting(switch_core_session_t *session)
|
||||||
{
|
{
|
||||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
const char *log_dir = NULL, *template_str = NULL;
|
const char *template_str = NULL;
|
||||||
char *expanded_vars = NULL;
|
char *expanded_vars = NULL;
|
||||||
|
|
||||||
if (globals.shutdown) {
|
if (globals.shutdown) {
|
||||||
|
@ -389,12 +403,8 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(log_dir = switch_channel_get_variable(channel, "cdr_pg_csv_base"))) {
|
if (switch_dir_make_recursive(globals.log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
||||||
log_dir = globals.log_dir;
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", globals.log_dir);
|
||||||
}
|
|
||||||
|
|
||||||
if (switch_dir_make_recursive(log_dir, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating %s\n", log_dir);
|
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +434,7 @@ static switch_status_t my_on_reporting(switch_core_session_t *session)
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
save_cdr(template_str, expanded_vars, log_dir);
|
save_cdr(template_str, expanded_vars);
|
||||||
|
|
||||||
if (expanded_vars != template_str) {
|
if (expanded_vars != template_str) {
|
||||||
free(expanded_vars);
|
free(expanded_vars);
|
||||||
|
@ -528,6 +538,8 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
|
||||||
globals.db_table = switch_core_strdup(pool, val);
|
globals.db_table = switch_core_strdup(pool, val);
|
||||||
} else if (!strcasecmp(var, "default-template")) {
|
} else if (!strcasecmp(var, "default-template")) {
|
||||||
globals.default_template = switch_core_strdup(pool, val);
|
globals.default_template = switch_core_strdup(pool, val);
|
||||||
|
} else if (!strcasecmp(var, "spool-format")) {
|
||||||
|
globals.spool_format = switch_core_strdup(pool, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -563,6 +575,9 @@ static switch_status_t load_config(switch_memory_pool_t *pool)
|
||||||
globals.default_template = switch_core_strdup(pool, "default");
|
globals.default_template = switch_core_strdup(pool, "default");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (zstr(globals.spool_format)) {
|
||||||
|
globals.spool_format = switch_core_strdup(pool, "csv");
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue