;
; 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
; 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
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
};
int64_t int64;
uint64_t uint64;
struct timeval tv;
- float floater;
+ double doubler;
} values;
};
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)));
}
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;
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));
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)
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;
}
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;
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)
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;
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),
[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!!",
};