Skip to content
Snippets Groups Projects
Commit 00421c99 authored by Wenpeng Song's avatar Wenpeng Song Committed by Sukru Senli
Browse files

5211: rotate cdr csv log when reaching the line limit

parent 327e3d80
No related branches found
No related tags found
No related merge requests found
...@@ -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,53 @@ static int build_csv_record(char *buf, size_t bufsize, struct ast_cdr *cdr) ...@@ -303,19 +315,53 @@ 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, "r"))) {
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 */ 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/2)) {
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 +370,16 @@ static int writefile(char *s, char *file_path) ...@@ -324,12 +370,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 +398,7 @@ static int csv_log(struct ast_cdr *cdr) ...@@ -348,7 +398,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)) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment