mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
CDRC config changes: renaming cdr_fields into content_fields, adding new header_fields and trailer_fields options
This commit is contained in:
@@ -130,7 +130,7 @@ func NewCdrc(cdrcCfgs map[string]*config.CdrcConfig, httpSkipTlsCheck bool, cdrs
|
||||
cdrc.cdrSourceIds[idx] = cfg.CdrSourceId
|
||||
cdrc.duMultiplyFactors[idx] = cfg.DataUsageMultiplyFactor
|
||||
cdrc.cdrFilters[idx] = cfg.CdrFilter
|
||||
cdrc.cdrFields[idx] = cfg.CdrFields
|
||||
cdrc.cdrFields[idx] = cfg.ContentFields
|
||||
idx += 1
|
||||
}
|
||||
// Before processing, make sure in and out folders exist
|
||||
@@ -249,6 +249,8 @@ func (self *Cdrc) processFile(filePath string) error {
|
||||
csvReader.Comma = self.csvSep
|
||||
recordsProcessor = NewCsvRecordsProcessor(csvReader, self.cdrFormat, fn, self.failedCallsPrefix,
|
||||
self.cdrSourceIds, self.duMultiplyFactors, self.cdrFilters, self.cdrFields, self.httpSkipTlsCheck, self.partialRecordsCache)
|
||||
} else if self.cdrFormat == utils.FWV {
|
||||
recordsProcessor = NewFwvRecordsProcessor(file)
|
||||
}
|
||||
procRowNr := 0
|
||||
timeStart := time.Now()
|
||||
|
||||
@@ -31,10 +31,10 @@ import (
|
||||
func TestCsvRecordForkCdr(t *testing.T) {
|
||||
cgrConfig, _ := config.NewDefaultCGRConfig()
|
||||
cdrcConfig := cgrConfig.CdrcProfiles["/var/log/cgrates/cdrc/in"][utils.META_DEFAULT]
|
||||
cdrcConfig.CdrFields = append(cdrcConfig.CdrFields, &config.CfgCdrField{Tag: "SupplierTest", Type: utils.CDRFIELD, CdrFieldId: "supplier", Value: []*utils.RSRField{&utils.RSRField{Id: "14"}}})
|
||||
cdrcConfig.CdrFields = append(cdrcConfig.CdrFields, &config.CfgCdrField{Tag: "DisconnectCauseTest", Type: utils.CDRFIELD, CdrFieldId: utils.DISCONNECT_CAUSE,
|
||||
cdrcConfig.ContentFields = append(cdrcConfig.ContentFields, &config.CfgCdrField{Tag: "SupplierTest", Type: utils.CDRFIELD, CdrFieldId: "supplier", Value: []*utils.RSRField{&utils.RSRField{Id: "14"}}})
|
||||
cdrcConfig.ContentFields = append(cdrcConfig.ContentFields, &config.CfgCdrField{Tag: "DisconnectCauseTest", Type: utils.CDRFIELD, CdrFieldId: utils.DISCONNECT_CAUSE,
|
||||
Value: []*utils.RSRField{&utils.RSRField{Id: "16"}}})
|
||||
csvProcessor := &CsvRecordsProcessor{cdrFormat: CSV, cdrSourceIds: []string{"TEST_CDRC"}, cdrFields: [][]*config.CfgCdrField{cdrcConfig.CdrFields}}
|
||||
csvProcessor := &CsvRecordsProcessor{cdrFormat: CSV, cdrSourceIds: []string{"TEST_CDRC"}, cdrFields: [][]*config.CfgCdrField{cdrcConfig.ContentFields}}
|
||||
cdrRow := []string{"firstField", "secondField"}
|
||||
_, err := csvProcessor.recordToStoredCdr(cdrRow, 0)
|
||||
if err == nil {
|
||||
|
||||
@@ -38,7 +38,9 @@ type CdrcConfig struct {
|
||||
CdrSourceId string // Source identifier for the processed CDRs
|
||||
CdrFilter utils.RSRFields // Filter CDR records to import
|
||||
PartialRecordCache time.Duration // Duration to cache partial records when not pairing
|
||||
CdrFields []*CfgCdrField // List of fields to be processed
|
||||
HeaderFields []*CfgCdrField
|
||||
ContentFields []*CfgCdrField
|
||||
TrailerFields []*CfgCdrField
|
||||
}
|
||||
|
||||
func (self *CdrcConfig) loadFromJsonCfg(jsnCfg *CdrcJsonCfg) error {
|
||||
@@ -90,8 +92,18 @@ func (self *CdrcConfig) loadFromJsonCfg(jsnCfg *CdrcJsonCfg) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Cdr_fields != nil {
|
||||
if self.CdrFields, err = CfgCdrFieldsFromCdrFieldsJsonCfg(*jsnCfg.Cdr_fields); err != nil {
|
||||
if jsnCfg.Header_fields != nil {
|
||||
if self.HeaderFields, err = CfgCdrFieldsFromCdrFieldsJsonCfg(*jsnCfg.Header_fields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Content_fields != nil {
|
||||
if self.ContentFields, err = CfgCdrFieldsFromCdrFieldsJsonCfg(*jsnCfg.Content_fields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if jsnCfg.Trailer_fields != nil {
|
||||
if self.TrailerFields, err = CfgCdrFieldsFromCdrFieldsJsonCfg(*jsnCfg.Trailer_fields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -111,10 +123,20 @@ func (self *CdrcConfig) Clone() *CdrcConfig {
|
||||
clnCdrc.CdrInDir = self.CdrInDir
|
||||
clnCdrc.CdrOutDir = self.CdrOutDir
|
||||
clnCdrc.CdrSourceId = self.CdrSourceId
|
||||
clnCdrc.CdrFields = make([]*CfgCdrField, len(self.CdrFields))
|
||||
for idx, fld := range self.CdrFields {
|
||||
clnCdrc.HeaderFields = make([]*CfgCdrField, len(self.HeaderFields))
|
||||
clnCdrc.ContentFields = make([]*CfgCdrField, len(self.ContentFields))
|
||||
clnCdrc.TrailerFields = make([]*CfgCdrField, len(self.TrailerFields))
|
||||
for idx, fld := range self.HeaderFields {
|
||||
clonedVal := *fld
|
||||
clnCdrc.CdrFields[idx] = &clonedVal
|
||||
clnCdrc.HeaderFields[idx] = &clonedVal
|
||||
}
|
||||
for idx, fld := range self.ContentFields {
|
||||
clonedVal := *fld
|
||||
clnCdrc.ContentFields[idx] = &clonedVal
|
||||
}
|
||||
for idx, fld := range self.TrailerFields {
|
||||
clonedVal := *fld
|
||||
clnCdrc.TrailerFields[idx] = &clonedVal
|
||||
}
|
||||
return clnCdrc
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"data_usage_multiply_factor": 0.000976563,
|
||||
"run_delay": 1,
|
||||
"cdr_source_id": "csv2", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"cdr_field_id": "tor", "value": "~7:s/^(voice|data|sms|generic)$/*$1/"},
|
||||
{"cdr_field_id": "answer_time", "value": "1"},
|
||||
{"cdr_field_id": "usage", "value": "~9:s/^(\\d+)$/${1}s/"},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"cdr_out_dir": "/tmp/cgrates/cdrc2/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"data_usage_multiply_factor": 0.000976563,
|
||||
"cdr_source_id": "csv2", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"cdr_field_id": "tor", "value": "~7:s/^(voice|data|sms|generic)$/*$1/"},
|
||||
{"cdr_field_id": "answer_time", "value": "2"},
|
||||
],
|
||||
|
||||
@@ -273,11 +273,11 @@ func (self *CGRConfig) checkConfigSanity() error {
|
||||
} else if cdrcInst.Cdrs == utils.INTERNAL && !self.CDRSEnabled {
|
||||
return errors.New("CDRS not enabled but referenced from CDRC")
|
||||
}
|
||||
if len(cdrcInst.CdrFields) == 0 {
|
||||
if len(cdrcInst.ContentFields) == 0 {
|
||||
return errors.New("CdrC enabled but no fields to be processed defined!")
|
||||
}
|
||||
if cdrcInst.CdrFormat == utils.CSV {
|
||||
for _, cdrFld := range cdrcInst.CdrFields {
|
||||
for _, cdrFld := range cdrcInst.ContentFields {
|
||||
for _, rsrFld := range cdrFld.Value {
|
||||
if _, errConv := strconv.Atoi(rsrFld.Id); errConv != nil && !rsrFld.IsStatic() {
|
||||
return fmt.Errorf("CDR fields must be indices in case of .csv files, have instead: %s", rsrFld.Id)
|
||||
|
||||
@@ -168,7 +168,8 @@ const CGRATES_CFG_JSON = `
|
||||
"cdr_source_id": "freeswitch_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_filter": "", // filter CDR records to import
|
||||
"partial_record_cache": "10s", // duration to cache partial records when not pairing
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"header_fields": [], // template of the import header fields
|
||||
"content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "2", "mandatory": true},
|
||||
{"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "3", "mandatory": true},
|
||||
{"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "4", "mandatory": true},
|
||||
@@ -182,6 +183,7 @@ const CGRATES_CFG_JSON = `
|
||||
{"tag": "answer_time", "cdr_field_id": "answer_time", "type": "cdrfield", "value": "12", "mandatory": true},
|
||||
{"tag": "usage", "cdr_field_id": "usage", "type": "cdrfield", "value": "13", "mandatory": true},
|
||||
],
|
||||
"trailer_fields": [], // template of the import trailer fields
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -259,6 +259,7 @@ func TestDfCdreJsonCfgs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDfCdrcJsonCfg(t *testing.T) {
|
||||
eFields := []*CdrFieldJsonCfg{}
|
||||
cdrFields := []*CdrFieldJsonCfg{
|
||||
&CdrFieldJsonCfg{Tag: utils.StringPointer("tor"), Cdr_field_id: utils.StringPointer("tor"), Type: utils.StringPointer(utils.CDRFIELD),
|
||||
Value: utils.StringPointer("2"), Mandatory: utils.BoolPointer(true)},
|
||||
@@ -300,13 +301,15 @@ func TestDfCdrcJsonCfg(t *testing.T) {
|
||||
Cdr_source_id: utils.StringPointer("freeswitch_csv"),
|
||||
Cdr_filter: utils.StringPointer(""),
|
||||
Partial_record_cache: utils.StringPointer("10s"),
|
||||
Cdr_fields: &cdrFields,
|
||||
Header_fields: &eFields,
|
||||
Content_fields: &cdrFields,
|
||||
Trailer_fields: &eFields,
|
||||
},
|
||||
}
|
||||
if cfg, err := dfCgrJsonCfg.CdrcJsonCfg(); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCfg, cfg) {
|
||||
t.Error("Received: ", cfg)
|
||||
t.Error("Received: ", cfg["*default"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -423,6 +426,7 @@ func TestDfUserServJsonCfg(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDfMailerJsonCfg(t *testing.T) {
|
||||
|
||||
eCfg := &MailerJsonCfg{
|
||||
Server: utils.StringPointer("localhost"),
|
||||
Auth_user: utils.StringPointer("cgrates"),
|
||||
@@ -466,15 +470,14 @@ func TestNewCgrJsonCfgFromFile(t *testing.T) {
|
||||
Cdr_in_dir: utils.StringPointer("/tmp/cgrates/cdrc2/in"),
|
||||
Cdr_out_dir: utils.StringPointer("/tmp/cgrates/cdrc2/out"),
|
||||
Cdr_source_id: utils.StringPointer("csv2"),
|
||||
Cdr_fields: &cdrFields,
|
||||
Content_fields: &cdrFields,
|
||||
},
|
||||
}
|
||||
if cfg, err := cgrJsonCfg.CdrcJsonCfg(); err != nil {
|
||||
t.Error(err)
|
||||
} else if !reflect.DeepEqual(eCfgCdrc, cfg) {
|
||||
t.Error("Received: ", cfg)
|
||||
t.Error("Received: ", cfg["CDRC-CSV2"])
|
||||
}
|
||||
|
||||
eCfgSmFs := &SmFsJsonCfg{
|
||||
Enabled: utils.BoolPointer(true),
|
||||
Connections: &[]*FsConnJsonCfg{
|
||||
|
||||
@@ -49,7 +49,8 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
CdrSourceId: "freeswitch_csv",
|
||||
CdrFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP),
|
||||
PartialRecordCache: time.Duration(10) * time.Second,
|
||||
CdrFields: []*CfgCdrField{
|
||||
HeaderFields: make([]*CfgCdrField, 0),
|
||||
ContentFields: []*CfgCdrField{
|
||||
&CfgCdrField{Tag: "tor", Type: "cdrfield", CdrFieldId: "tor", Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
&CfgCdrField{Tag: "accid", Type: "cdrfield", CdrFieldId: "accid", Value: utils.ParseRSRFieldsMustCompile("3", utils.INFIELD_SEP),
|
||||
@@ -75,6 +76,7 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
&CfgCdrField{Tag: "usage", Type: "cdrfield", CdrFieldId: "usage", Value: utils.ParseRSRFieldsMustCompile("13", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
},
|
||||
TrailerFields: make([]*CfgCdrField, 0),
|
||||
},
|
||||
}
|
||||
eCgrCfg.CdrcProfiles["/tmp/cgrates/cdrc1/in"] = map[string]*CdrcConfig{
|
||||
@@ -90,7 +92,8 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
CdrOutDir: "/tmp/cgrates/cdrc1/out",
|
||||
CdrSourceId: "csv1",
|
||||
CdrFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP),
|
||||
CdrFields: []*CfgCdrField{
|
||||
HeaderFields: make([]*CfgCdrField, 0),
|
||||
ContentFields: []*CfgCdrField{
|
||||
&CfgCdrField{Tag: "tor", Type: "cdrfield", CdrFieldId: "tor", Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
&CfgCdrField{Tag: "accid", Type: "cdrfield", CdrFieldId: "accid", Value: utils.ParseRSRFieldsMustCompile("3", utils.INFIELD_SEP),
|
||||
@@ -116,6 +119,7 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
&CfgCdrField{Tag: "usage", Type: "cdrfield", CdrFieldId: "usage", Value: utils.ParseRSRFieldsMustCompile("13", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
},
|
||||
TrailerFields: make([]*CfgCdrField, 0),
|
||||
},
|
||||
}
|
||||
eCgrCfg.CdrcProfiles["/tmp/cgrates/cdrc2/in"] = map[string]*CdrcConfig{
|
||||
@@ -131,12 +135,14 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
CdrOutDir: "/tmp/cgrates/cdrc2/out",
|
||||
CdrSourceId: "csv2",
|
||||
CdrFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP),
|
||||
CdrFields: []*CfgCdrField{
|
||||
HeaderFields: make([]*CfgCdrField, 0),
|
||||
ContentFields: []*CfgCdrField{
|
||||
&CfgCdrField{Tag: "", Type: "", CdrFieldId: "tor", Value: utils.ParseRSRFieldsMustCompile("~7:s/^(voice|data|sms|generic)$/*$1/", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: false},
|
||||
&CfgCdrField{Tag: "", Type: "", CdrFieldId: "answer_time", Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: false},
|
||||
},
|
||||
TrailerFields: make([]*CfgCdrField, 0),
|
||||
},
|
||||
}
|
||||
eCgrCfg.CdrcProfiles["/tmp/cgrates/cdrc3/in"] = map[string]*CdrcConfig{
|
||||
@@ -152,7 +158,8 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
CdrOutDir: "/tmp/cgrates/cdrc3/out",
|
||||
CdrSourceId: "csv3",
|
||||
CdrFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP),
|
||||
CdrFields: []*CfgCdrField{
|
||||
HeaderFields: make([]*CfgCdrField, 0),
|
||||
ContentFields: []*CfgCdrField{
|
||||
&CfgCdrField{Tag: "tor", Type: "cdrfield", CdrFieldId: "tor", Value: utils.ParseRSRFieldsMustCompile("2", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
&CfgCdrField{Tag: "accid", Type: "cdrfield", CdrFieldId: "accid", Value: utils.ParseRSRFieldsMustCompile("3", utils.INFIELD_SEP),
|
||||
@@ -178,6 +185,7 @@ func TestLoadCdrcConfigMultipleFiles(t *testing.T) {
|
||||
&CfgCdrField{Tag: "usage", Type: "cdrfield", CdrFieldId: "usage", Value: utils.ParseRSRFieldsMustCompile("13", utils.INFIELD_SEP),
|
||||
FieldFilter: utils.ParseRSRFieldsMustCompile("", utils.INFIELD_SEP), Width: 0, Strip: "", Padding: "", Layout: "", Mandatory: true},
|
||||
},
|
||||
TrailerFields: make([]*CfgCdrField, 0),
|
||||
},
|
||||
}
|
||||
if !reflect.DeepEqual(eCgrCfg.CdrcProfiles, cgrCfg.CdrcProfiles) {
|
||||
|
||||
@@ -139,7 +139,9 @@ type CdrcJsonCfg struct {
|
||||
Cdr_filter *string
|
||||
Max_open_files *int
|
||||
Partial_record_cache *string
|
||||
Cdr_fields *[]*CdrFieldJsonCfg
|
||||
Header_fields *[]*CdrFieldJsonCfg
|
||||
Content_fields *[]*CdrFieldJsonCfg
|
||||
Trailer_fields *[]*CdrFieldJsonCfg
|
||||
}
|
||||
|
||||
// SM-FreeSWITCH config section
|
||||
|
||||
@@ -148,7 +148,8 @@
|
||||
// "cdr_source_id": "freeswitch_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
// "cdr_filter": "", // filter CDR records to import
|
||||
// "partial_record_cache": "10s", // duration to cache partial records when not pairing
|
||||
// "cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
// "header_fields": [], // template of the import header fields
|
||||
// "content_fields":[ // import content_fields template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
// {"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "2", "mandatory": true},
|
||||
// {"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "3", "mandatory": true},
|
||||
// {"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "4", "mandatory": true},
|
||||
@@ -162,7 +163,8 @@
|
||||
// {"tag": "answer_time", "cdr_field_id": "answer_time", "type": "cdrfield", "value": "12", "mandatory": true},
|
||||
// {"tag": "usage", "cdr_field_id": "usage", "type": "cdrfield", "value": "13", "mandatory": true},
|
||||
// ],
|
||||
// },
|
||||
// "trailer_fields": [], // template of the import trailer fields
|
||||
// }
|
||||
//},
|
||||
|
||||
|
||||
|
||||
@@ -24,20 +24,20 @@
|
||||
|
||||
"cdrc": {
|
||||
"FLATSTORE": {
|
||||
"enabled": true, // enable CDR client functionality
|
||||
"cdrs": "internal", // address where to reach CDR server. <internal|x.y.z.y:1234>
|
||||
"cdr_format": "opensips_flatstore", // CDR file format <csv|freeswitch_csv|fwv|opensips_flatstore>
|
||||
"field_separator": "|", // separator used in case of csv files
|
||||
"run_delay": 0, // sleep interval in seconds between consecutive runs, 0 to use automation via inotify
|
||||
"max_open_files": 1024, // maximum simultaneous files to process
|
||||
"data_usage_multiply_factor": 1024, // conversion factor for data usage
|
||||
"cdr_in_dir": "/tmp/cgr_flatstore/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
"enabled": true, // enable CDR client functionality
|
||||
"cdrs": "internal", // address where to reach CDR server. <internal|x.y.z.y:1234>
|
||||
"cdr_format": "opensips_flatstore", // CDR file format <csv|freeswitch_csv|fwv|opensips_flatstore>
|
||||
"field_separator": "|", // separator used in case of csv files
|
||||
"run_delay": 0, // sleep interval in seconds between consecutive runs, 0 to use automation via inotify
|
||||
"max_open_files": 1024, // maximum simultaneous files to process
|
||||
"data_usage_multiply_factor": 1024, // conversion factor for data usage
|
||||
"cdr_in_dir": "/tmp/cgr_flatstore/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgr_flatstore/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"failed_calls_prefix": "missed_calls", // used in case of flatstore CDRs to avoid searching for BYE records
|
||||
"cdr_source_id": "flatstore", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_filter": "", // filter CDR records to import
|
||||
"partial_record_cache": "1s", // duration to cache partial records when not pairing
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"failed_calls_prefix": "missed_calls", // used in case of flatstore CDRs to avoid searching for BYE records
|
||||
"cdr_source_id": "flatstore", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_filter": "", // filter CDR records to import
|
||||
"partial_record_cache": "1s", // duration to cache partial records when not pairing
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"tag": "Tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "^*voice", "mandatory": true},
|
||||
{"tag": "AccId", "cdr_field_id": "accid", "type": "cdrfield", "mandatory": true},
|
||||
{"tag": "ReqType", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "7", "mandatory": true},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"cdr_in_dir": "/tmp/cgrates/cdrc_fs/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgrates/cdrc_fs/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"cdr_source_id": "fs_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "^*voice", "mandatory": true},
|
||||
{"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "10", "mandatory": true},
|
||||
{"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "^rated", "mandatory": true},
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
"cdr_in_dir": "/tmp/cgrates/cdrc2/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgrates/cdrc2/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"cdr_source_id": "csv2", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"cdr_field_id": "tor", "value": "~7:s/^(voice|data|sms|generic)$/*$1/"},
|
||||
{"cdr_field_id": "accid", "value": "0"},
|
||||
{"cdr_field_id": "reqtype", "value": "^rated"},
|
||||
@@ -50,7 +50,7 @@
|
||||
"cdr_in_dir": "/tmp/cgrates/cdrc3/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgrates/cdrc3/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"cdr_source_id": "csv3", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"cdr_field_id": "tor", "value": "^*voice"},
|
||||
{"cdr_field_id": "accid", "value": "~3:s/^(\\d{2})\\.(\\d{2})\\.(\\d{4})\\s{2}(\\d{2}):(\\d{2}):(\\d{2})$/$1$2$3$4$5$6/"},
|
||||
{"cdr_field_id": "reqtype", "value": "^rated"},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"cdr_in_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/in", // absolute path towards the directory where the CDRs are stored
|
||||
"cdr_out_dir": "/tmp/cgr_fsevsock/cgrates/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
"cdr_source_id": "fs_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
"cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
"content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
{"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "^*voice", "mandatory": true},
|
||||
{"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "10", "mandatory": true},
|
||||
{"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "^*pseudoprepaid", "mandatory": true},
|
||||
|
||||
@@ -184,7 +184,7 @@
|
||||
// "cdr_out_dir": "/var/log/cgrates/cdrc/out", // absolute path towards the directory where processed CDRs will be moved
|
||||
// "cdr_source_id": "freeswitch_csv", // free form field, tag identifying the source of the CDRs within CDRS database
|
||||
// "cdr_filter": "", // Filter CDR records to import
|
||||
// "cdr_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
// "content_fields":[ // import template, tag will match internally CDR field, in case of .csv value will be represented by index of the field value
|
||||
// {"tag": "tor", "cdr_field_id": "tor", "type": "cdrfield", "value": "2", "mandatory": true},
|
||||
// {"tag": "accid", "cdr_field_id": "accid", "type": "cdrfield", "value": "3", "mandatory": true},
|
||||
// {"tag": "reqtype", "cdr_field_id": "reqtype", "type": "cdrfield", "value": "4", "mandatory": true},
|
||||
|
||||
@@ -123,6 +123,7 @@ const (
|
||||
META_DEFAULT = "*default"
|
||||
STATIC_VALUE_PREFIX = "^"
|
||||
CSV = "csv"
|
||||
FWV = "fwv"
|
||||
DRYRUN = "dry_run"
|
||||
COMBIMED = "combimed"
|
||||
INTERNAL = "internal"
|
||||
|
||||
Reference in New Issue
Block a user