Skip to content
Snippets Groups Projects

Draft: rotate cdr csv log when reach max row

Closed Wenpeng Song requested to merge csv_rotate into devel
8 files
+ 179
12
Compare changes
  • Side-by-side
  • Inline
Files
8
+ 63
12
@@ -48,6 +48,8 @@
@@ -48,6 +48,8 @@
#define CSV_LOG_DIR "/cdr-csv"
#define CSV_LOG_DIR "/cdr-csv"
#define CSV_MASTER "/Master.csv"
#define CSV_MASTER "/Master.csv"
 
#define CSV_MASTER_OLD "/Master_old.csv"
 
#define CSV_MASTER_COUNT "/Master_count"
#define DATE_FORMAT "%Y-%m-%d %T"
#define DATE_FORMAT "%Y-%m-%d %T"
@@ -57,8 +59,11 @@ static int loguniqueid = 0;
@@ -57,8 +59,11 @@ static int loguniqueid = 0;
static int loguserfield = 0;
static int loguserfield = 0;
static int loaded = 0;
static int loaded = 0;
static int newcdrcolumns = 0;
static int newcdrcolumns = 0;
 
static int maxrow = 100; /* max row stored in csv file before rotate */
static const char config[] = "cdr.conf";
static const char config[] = "cdr.conf";
static char file_csv_master[PATH_MAX];
static char file_csv_master[PATH_MAX];
 
static char file_csv_old[PATH_MAX];
 
static char file_csv_master_count[PATH_MAX];
/* #define CSV_LOGUNIQUEID 1 */
/* #define CSV_LOGUNIQUEID 1 */
/* #define CSV_LOGUSERFIELD 1 */
/* #define CSV_LOGUSERFIELD 1 */
@@ -113,6 +118,7 @@ static int load_config(int reload)
@@ -113,6 +118,7 @@ static int load_config(int reload)
loguniqueid = 0;
loguniqueid = 0;
loguserfield = 0;
loguserfield = 0;
newcdrcolumns = 0;
newcdrcolumns = 0;
 
maxrow = 100;
if (!(v = ast_variable_browse(cfg, "csv"))) {
if (!(v = ast_variable_browse(cfg, "csv"))) {
ast_config_destroy(cfg);
ast_config_destroy(cfg);
@@ -123,6 +129,10 @@ static int load_config(int reload)
@@ -123,6 +129,10 @@ static int load_config(int reload)
ast_mutex_lock(&f_lock);
ast_mutex_lock(&f_lock);
snprintf(file_csv_master, sizeof(file_csv_master),
snprintf(file_csv_master, sizeof(file_csv_master),
"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER);
"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER);
 
snprintf(file_csv_old, sizeof(file_csv_old),
 
"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER_OLD);
 
snprintf(file_csv_master_count, sizeof(file_csv_master_count),
 
"%s/%s/%s", ast_config_AST_LOG_DIR, CSV_LOG_DIR, CSV_MASTER_COUNT);
ast_mutex_unlock(&f_lock);
ast_mutex_unlock(&f_lock);
for (; v; v = v->next) {
for (; v; v = v->next) {
@@ -137,6 +147,8 @@ static int load_config(int reload)
@@ -137,6 +147,8 @@ static int load_config(int reload)
loguserfield = ast_true(v->value);
loguserfield = ast_true(v->value);
} else if (!strcasecmp(v->name, "newcdrcolumns")) {
} else if (!strcasecmp(v->name, "newcdrcolumns")) {
newcdrcolumns = ast_true(v->value);
newcdrcolumns = ast_true(v->value);
 
} else if (!strcasecmp(v->name, "maxrow")) {
 
maxrow = atoi(v->value);
}
}
}
}
@@ -303,19 +315,54 @@ static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
@@ -303,19 +315,54 @@ static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr)
return -1;
return -1;
}
}
static int writefile(char *s, char *file_path)
static int getrowcount(char *file_path_count)
{
{
FILE *f;
/* get current recorded count from file*/
/* because of the absolutely unconditional need for the
FILE *f;
highest reliability possible in writing billing records,
int rowcount = 0;
we open write and close the log file each time */
if (!(f = fopen(file_path_count, "a+"))) {
if (!(f = fopen(file_path, "a"))) {
ast_log(LOG_ERROR, "Unable to open file %s : %s\n", file_path_count, strerror(errno));
ast_log(LOG_ERROR, "Unable to open file %s : %s\n", file_path, strerror(errno));
return -1;
return -1;
}
}
fputs(s, f);
fscanf(f, "%d", &rowcount);
fflush(f); /* be particularly anal here */
fflush(f);
fclose(f);
fclose(f);
 
return rowcount;
 
}
 
 
static int writerowcount(char *file_path_count, int count)
 
{
 
/* write count number to file */
 
FILE *f;
 
if (!(f = fopen(file_path_count, "w"))) {
 
ast_log(LOG_ERROR, "Unable to open file %s : %s\n", file_path_count, strerror(errno));
 
return -1;
 
}
 
fprintf(f, "%d\n", count);
 
fflush(f);
 
fclose(f);
 
return 0;
 
}
 
 
static int writefile(char *s, char *file_path, char *file_path_old, char *file_path_count)
 
{
 
FILE *f;
 
int rowcount = getrowcount(file_path_count);
 
/* because of the absolutely unconditional need for the
 
highest reliability possible in writing billing records,
 
we open write and close the log file each time */
 
if (rowcount >= maxrow) {
 
rename(file_path, file_path_old); /* rotate(rename as back up) when reach max row */
 
rowcount = 0; /* clear row count */
 
}
 
if (!(f = fopen(file_path, "a"))) {
 
ast_log(LOG_ERROR, "Unable to open file %s : %s\n", file_path, strerror(errno));
 
return -1;
 
}
 
fputs(s, f);
 
fflush(f); /* be particularly anal here */
 
fclose(f);
 
writerowcount(file_path_count, rowcount+1); /* update row count record */
return 0;
return 0;
}
}
@@ -324,12 +371,16 @@ static int writefile(char *s, char *file_path)
@@ -324,12 +371,16 @@ static int writefile(char *s, char *file_path)
static int writefile_account(char *s, char *acc)
static int writefile_account(char *s, char *acc)
{
{
char file_account[PATH_MAX];
char file_account[PATH_MAX];
 
char file_account_old[PATH_MAX];
 
char file_account_count[PATH_MAX];
if (strchr(acc, '/') || (acc[0] == '.')) {
if (strchr(acc, '/') || (acc[0] == '.')) {
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
ast_log(LOG_WARNING, "Account code '%s' insecure for writing file\n", acc);
return -1;
return -1;
}
}
snprintf(file_account, sizeof(file_account), "%s/%s/%s.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
snprintf(file_account, sizeof(file_account), "%s/%s/%s.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
return writefile(s, file_account);
snprintf(file_account_old, sizeof(file_account_old), "%s/%s/%s_old.csv", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
 
snprintf(file_account_count, sizeof(file_account_count), "%s/%s/%s_count", ast_config_AST_LOG_DIR,CSV_LOG_DIR, acc);
 
return writefile(s, file_account, file_account_old, file_account_count);
}
}
static int csv_log(struct ast_cdr *cdr)
static int csv_log(struct ast_cdr *cdr)
@@ -348,7 +399,7 @@ static int csv_log(struct ast_cdr *cdr)
@@ -348,7 +399,7 @@ static int csv_log(struct ast_cdr *cdr)
}
}
ast_mutex_lock(&f_lock);
ast_mutex_lock(&f_lock);
if (writefile(buf, file_csv_master))
if (writefile(buf, file_csv_master, file_csv_old, file_csv_master_count))
ast_log(LOG_WARNING, "Unable to write CSV record to master '%s' : %s\n", file_csv_master, strerror(errno));
ast_log(LOG_WARNING, "Unable to write CSV record to master '%s' : %s\n", file_csv_master, strerror(errno));
if (accountlogs && !ast_strlen_zero(cdr->accountcode)) {
if (accountlogs && !ast_strlen_zero(cdr->accountcode)) {
Loading