mirror of
https://github.com/asterisk/asterisk.git
synced 2026-05-07 22:04:00 +00:00
res_cdrel_custom: Resolve several formatting issues.
Several issues are resolved: * Internally, floats were used for timestamp values but this could result in wrapping so they've been changed to doubles. * Historically, the default CEL eventtime format is `<seconds>.<microseconds>` with `<microseconds>` always being 6 digits. This should have continued to be the case but res_cdrel_custom wasn't checking the `dateformat` setting in cel.conf and was defaulting to `%F %T`. res_cdrel_custom now gets the default date format from cel.conf, which will be whatever the `dateformat` parameter is set to or `<seconds>.<microseconds>` if not set. * The timeval field formatter for both CDR and CEL wasn't handling custom strftime format strings correctly. This is now fixed so you should be able to specifiy custom strftime format strings for the CEL `eventtime` and CDR `start`, `answer` and `end` fields. For example: `eventtime(%FT%T%z)`. Resolves: #1844 Resolves: #1845
This commit is contained in:
@@ -106,7 +106,8 @@
|
||||
;
|
||||
; The default output format for the "start", "answer" and "end" timestamp fields
|
||||
; is the "%Y-%m-%d %T" strftime string format however you can also format those
|
||||
; fields as an int64 or a float: `start(int64),answer(float),end`.
|
||||
; fields as an int64 or a double: `start(int64)` or `start(double)` or
|
||||
; provide your own strftime format string: `start(%FT%T%z)`.
|
||||
;
|
||||
; The "disposition" and "amaflags" are formatted as their string names like
|
||||
; "ANSWERED" and "DOCUMENTATION" by default but if you just want the numbers and
|
||||
|
||||
@@ -111,9 +111,12 @@
|
||||
; you can force the uniqueid field to not be quoted with `uniqueid(noquote)`. The
|
||||
; example in fields above shows this.
|
||||
;
|
||||
; The default output format for the "EventTime" timestamp field is the "%Y-%m-%d %T"
|
||||
; strftime string format however you can also format the field as an int64 or a
|
||||
; float: `eventtime(int64)` or `eventtime(float)`.
|
||||
; The default output format for the "EventTime" timestamp field is taken from the
|
||||
; "dateformat" parameter in cel.conf. If that's not set, the default is
|
||||
; "<seconds>.<microseconds>" where "<microseconds>" is always 6 digits with
|
||||
; leading zeros. You can also format the field as an int64 or a double:
|
||||
; `eventtime(int64)` or `eventtime(double)` or provide your own strftime
|
||||
; format string: `eventtime(%FT%T%z)`.
|
||||
;
|
||||
; Unlike CDRs, the "amaflags" field is output as its numerical value by default
|
||||
; for historical reasons. You can output it as its friendly string with
|
||||
|
||||
@@ -78,12 +78,13 @@ enum cdrel_data_type {
|
||||
cdrel_type_uservar,
|
||||
cdrel_type_event_type,
|
||||
cdrel_type_event_enum,
|
||||
cdrel_type_cel_timefmt,
|
||||
cdrel_data_type_strings_end,
|
||||
cdrel_type_int32,
|
||||
cdrel_type_uint32,
|
||||
cdrel_type_int64,
|
||||
cdrel_type_uint64,
|
||||
cdrel_type_float,
|
||||
cdrel_type_double,
|
||||
cdrel_data_type_end
|
||||
};
|
||||
|
||||
@@ -180,7 +181,7 @@ struct cdrel_value {
|
||||
int64_t int64;
|
||||
uint64_t uint64;
|
||||
struct timeval tv;
|
||||
float floater;
|
||||
double doubler;
|
||||
} values;
|
||||
};
|
||||
|
||||
|
||||
@@ -432,6 +432,7 @@ static struct cdrel_field *field_alloc(struct cdrel_config *config, const char *
|
||||
if (strchr(qualifier, '%') != NULL) {
|
||||
data_swap = ast_strdupa(qualifier);
|
||||
ast_set_flag(&field_flags, cdrel_flag_format_spec);
|
||||
forced_output_data_type = cdrel_type_string;
|
||||
ast_debug(3, " Using qualifier '%s' for field '%s' flags: %s\n", qualifier,
|
||||
field_name, ast_str_tmp(128, cdrel_get_field_flags(&field_flags, &STR_TMP)));
|
||||
}
|
||||
@@ -466,6 +467,17 @@ static struct cdrel_field *field_alloc(struct cdrel_config *config, const char *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (ast_test_flag(&field_flags, cdrel_flag_format_spec)
|
||||
&& registered_field->input_data_type != cdrel_type_timeval) {
|
||||
ast_log(LOG_WARNING, "%s->%s: Custom format '%s' ignored for field '%s'."
|
||||
" Only timeval types can use custom format strings.\n",
|
||||
cdrel_basename(config->config_filename), cdrel_basename(config->output_filename),
|
||||
data, field_name);
|
||||
forced_output_data_type = cdrel_data_type_end;
|
||||
ast_clear_flag(&field_flags, cdrel_flag_format_spec);
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
field = ast_calloc(1, sizeof(*registered_field) + strlen(input_field_template) + 1);
|
||||
if (!field) {
|
||||
return NULL;
|
||||
@@ -1127,7 +1139,7 @@ static struct cdrel_config *load_text_file_legacy_config(enum cdrel_record_type
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ast_log(LOG_NOTICE, "%s->%s: Logging %s records\n",
|
||||
ast_log(LOG_NOTICE, "%s->%s: Logging legacy %s records as advanced\n",
|
||||
cdrel_basename(config->config_filename), cdrel_basename(config->output_filename),
|
||||
RECORD_TYPE_STR(config->record_type));
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ DEFINE_FORMATTER(uint32, uint32, uint32_t, "%u")
|
||||
DEFINE_FORMATTER(int32, int32, int32_t, "%d")
|
||||
DEFINE_FORMATTER(uint64, uint64, uint64_t, "%lu")
|
||||
DEFINE_FORMATTER(int64, int64, int64_t, "%ld")
|
||||
DEFINE_FORMATTER(float, floater, float, "%.1f")
|
||||
DEFINE_FORMATTER(double, doubler, double, "%.6f")
|
||||
|
||||
static int format_timeval(struct cdrel_config *config,
|
||||
struct cdrel_field *field, struct cdrel_value *input_value, struct cdrel_value *output_value)
|
||||
@@ -134,11 +134,20 @@ static int format_timeval(struct cdrel_config *config,
|
||||
output_value->data_type = cdrel_type_int64;
|
||||
output_value->values.int64 = input_value->values.tv.tv_sec;
|
||||
return format_int64(config, field, output_value, output_value);
|
||||
} else if (field->output_data_type == cdrel_type_float) {
|
||||
output_value->data_type = cdrel_type_float;
|
||||
output_value->values.floater = ((float)input_value->values.tv.tv_sec) + ((float)input_value->values.tv.tv_usec) / 1000000.0;
|
||||
return format_float(config, field, output_value, output_value);
|
||||
} else if (!ast_strlen_zero(field->data)) {
|
||||
} else if (field->output_data_type == cdrel_type_double) {
|
||||
output_value->data_type = cdrel_type_double;
|
||||
output_value->values.doubler = ((double)input_value->values.tv.tv_sec) + ((double)input_value->values.tv.tv_usec) / 1000000.0;
|
||||
return format_double(config, field, output_value, output_value);
|
||||
} else if (field->output_data_type == cdrel_type_cel_timefmt) {
|
||||
res = ast_cel_format_eventtime(input_value->values.tv, tempbuf, 64);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
input_value->values.string = tempbuf;
|
||||
input_value->data_type = cdrel_type_string;
|
||||
output_value->data_type = cdrel_type_string;
|
||||
return format_string(config, field, input_value, output_value);
|
||||
} else if (!ast_strlen_zero(field->data)) {
|
||||
format = field->data;
|
||||
}
|
||||
|
||||
@@ -186,7 +195,7 @@ int load_formatters(void)
|
||||
cdrel_field_formatters[cdrel_type_int64] = format_int64;
|
||||
cdrel_field_formatters[cdrel_type_uint64] = format_uint64;
|
||||
cdrel_field_formatters[cdrel_type_timeval] = format_timeval;
|
||||
cdrel_field_formatters[cdrel_type_float] = format_float;
|
||||
cdrel_field_formatters[cdrel_type_double] = format_double;
|
||||
cdrel_field_formatters[cdrel_type_amaflags] = format_amaflags;
|
||||
cdrel_field_formatters[cdrel_type_disposition] = format_disposition;
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ DEFINE_CDR_GETTER(uint32, uint32, uint32_t)
|
||||
DEFINE_CDR_GETTER(int64, int64, int64_t)
|
||||
DEFINE_CDR_GETTER(uint64, uint64, uint64_t)
|
||||
DEFINE_CDR_GETTER(tv, timeval, struct timeval)
|
||||
DEFINE_CDR_GETTER(floater, float, float)
|
||||
DEFINE_CDR_GETTER(doubler, double, double)
|
||||
|
||||
static int cdr_get_literal(void *record, struct cdrel_config *config,
|
||||
struct cdrel_field *field, struct cdrel_value *value)
|
||||
@@ -108,7 +108,7 @@ int load_cdr(void)
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_int64] = cdr_get_int64;
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_uint64] = cdr_get_uint64;
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_timeval] = cdr_get_timeval;
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_float] = cdr_get_float;
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_double] = cdr_get_double;
|
||||
cdrel_field_getters[cdrel_record_cdr][cdrel_type_uservar] = cdr_get_uservar;
|
||||
cdrel_dummy_channel_allocators[cdrel_record_cdr] = dummy_chan_alloc_cdr;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
static const struct cdrel_field cdrel_field_registry[] = {
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_EVENT_ENUM, "eventenum", cdrel_type_event_enum, cdrel_type_string),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_EVENT_TYPE, "eventtype", cdrel_type_event_type, cdrel_type_string),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_EVENT_TIME, "eventtime", cdrel_type_timeval, cdrel_type_string),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_EVENT_TIME, "eventtime", cdrel_type_timeval, cdrel_type_cel_timefmt),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_EVENT_TIME_USEC, "eventtimeusec", cdrel_type_uint32, cdrel_type_uint32),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_USEREVENT_NAME, "usereventname", cdrel_type_string, cdrel_type_string),
|
||||
REGISTER_FIELD(cdrel_record_cel, AST_EVENT_IE_CEL_USEREVENT_NAME, "userdeftype", cdrel_type_string, cdrel_type_string),
|
||||
|
||||
@@ -166,12 +166,13 @@ const char *cdrel_data_type_map[] = {
|
||||
[cdrel_type_uservar] = "uservar",
|
||||
[cdrel_type_event_type] = "event_type",
|
||||
[cdrel_type_event_enum] = "event_enum",
|
||||
[cdrel_type_cel_timefmt] = "cel_timefmt",
|
||||
[cdrel_data_type_strings_end] = "!!STRINGS END!!",
|
||||
[cdrel_type_int32] = "int32",
|
||||
[cdrel_type_uint32] = "uint32",
|
||||
[cdrel_type_int64] = "int64",
|
||||
[cdrel_type_uint64] = "uint64",
|
||||
[cdrel_type_float] = "float",
|
||||
[cdrel_type_double] = "double",
|
||||
[cdrel_data_type_end] = "!!END!!",
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user