diff --git a/config/cdrstatsconfig.go b/config/cdrstatsconfig.go index a6a6ab10c..49fc837d4 100644 --- a/config/cdrstatsconfig.go +++ b/config/cdrstatsconfig.go @@ -20,12 +20,155 @@ package config import ( "code.google.com/p/goconf/conf" + "github.com/cgrates/cgrates/utils" + "strconv" "time" ) // Parse the configuration file for CDRStatConfigs -func ParseCfgCDRStatConfigs(c *conf.ConfigFile) ([]*CdrStatsConfig, error) { - return nil, nil +func ParseCfgDefaultCDRStatsConfig(c *conf.ConfigFile) (*CdrStatsConfig, error) { + var err error + csCfg := new(CdrStatsConfig) + csCfg.Id = utils.DEFAULT_RUNID + if hasOpt := c.HasOption("cdrstats", "queue_length"); hasOpt { + csCfg.QueueLength, _ = c.GetInt("cdrstats", "queue_length") + } + if hasOpt := c.HasOption("cdrstats", "time_window"); hasOpt { + durStr, _ := c.GetString("cdrstats", "time_window") + if csCfg.TimeWindow, err = utils.ParseDurationWithSecs(durStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "metrics"); hasOpt { + metricsStr, _ := c.GetString("cdrstats", "metrics") + if csCfg.Metrics, err = ConfigSlice(metricsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "setup_interval"); hasOpt { + setupIntervalStr, _ := c.GetString("cdrstats", "setup_interval") + if len(setupIntervalStr) != 0 { // If we parse empty, will get empty time, we prefer nil + if setupIntervalSlc, err := ConfigSlice(setupIntervalStr); err != nil { + return nil, err + } else { + for _, setupTimeStr := range setupIntervalSlc { + if setupTime, err := utils.ParseTimeDetectLayout(setupTimeStr); err != nil { + return nil, err + } else { + csCfg.SetupInterval = append(csCfg.SetupInterval, setupTime) + } + } + } + } + } + if hasOpt := c.HasOption("cdrstats", "tors"); hasOpt { + torsStr, _ := c.GetString("cdrstats", "tors") + if csCfg.TOR, err = ConfigSlice(torsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "cdr_hosts"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "cdr_hosts") + if csCfg.CdrHost, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "cdr_sources"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "cdr_sources") + if csCfg.CdrSource, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "req_types"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "req_types") + if csCfg.ReqType, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "directions"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "directions") + if csCfg.Direction, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "tenants"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "tenants") + if csCfg.Tenant, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "categories"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "categories") + if csCfg.Category, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "accounts"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "accounts") + if csCfg.Account, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "subjects"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "subjects") + if csCfg.Subject, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "destination_prefixes"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "destination_prefixes") + if csCfg.DestinationPrefix, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "usage_interval"); hasOpt { + usageIntervalStr, _ := c.GetString("cdrstats", "usage_interval") + if usageIntervalSlc, err := ConfigSlice(usageIntervalStr); err != nil { + return nil, err + } else { + for _, usageDurStr := range usageIntervalSlc { + if usageDur, err := utils.ParseDurationWithSecs(usageDurStr); err != nil { + return nil, err + } else { + csCfg.UsageInterval = append(csCfg.UsageInterval, usageDur) + } + } + } + } + if hasOpt := c.HasOption("cdrstats", "mediation_run_ids"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "mediation_run_ids") + if csCfg.MediationRunIds, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "rated_accounts"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "rated_accounts") + if csCfg.RatedAccount, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "rated_subjects"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "rated_subjects") + if csCfg.RatedSubject, err = ConfigSlice(valsStr); err != nil { + return nil, err + } + } + if hasOpt := c.HasOption("cdrstats", "cost_intervals"); hasOpt { + valsStr, _ := c.GetString("cdrstats", "cost_intervals") + if costSlc, err := ConfigSlice(valsStr); err != nil { + return nil, err + } else { + for _, costStr := range costSlc { + if cost, err := strconv.ParseFloat(costStr, 64); err != nil { + return nil, err + } else { + csCfg.CostInterval = append(csCfg.CostInterval, cost) + } + } + } + } + + return csCfg, nil } type CdrStatsConfig struct { @@ -49,5 +192,4 @@ type CdrStatsConfig struct { RatedAccount []string RatedSubject []string CostInterval []float64 // 2 or less items, (>=Cost, CDRSStats string // Address where to reach the Mediator. <""|intenal> CDRStatsEnabled bool // Enable CDR Stats service - CDRStatConfigs []*CdrStatsConfig // Active cdr stats configuration instances + CDRStatConfig *CdrStatsConfig // Active cdr stats configuration instances CdreDefaultInstance *CdreConfig // Will be used in the case no specific one selected by API CdrcEnabled bool // Enable CDR client functionality CdrcCdrs string // Address where to reach CDR server @@ -179,6 +179,7 @@ func (self *CGRConfig) setDefaults() error { self.CDRSMediator = "" self.CDRSStats = "" self.CDRStatsEnabled = false + self.CDRStatConfig = &CdrStatsConfig{Id: utils.DEFAULT_RUNID, QueueLength: 50, TimeWindow: time.Duration(1) * time.Hour, Metrics: []string{"ASR", "ACD", "ACC"}} self.CdreDefaultInstance, _ = NewDefaultCdreConfig() self.CdrcEnabled = false self.CdrcCdrs = utils.INTERNAL @@ -429,6 +430,9 @@ func loadConfig(c *conf.ConfigFile) (*CGRConfig, error) { if hasOpt = c.HasOption("cdrstats", "enabled"); hasOpt { cfg.CDRStatsEnabled, _ = c.GetBool("cdrstats", "enabled") } + if cfg.CDRStatConfig, err = ParseCfgDefaultCDRStatsConfig(c); err != nil { + return nil, err + } if hasOpt = c.HasOption("cdre", "cdr_format"); hasOpt { cfg.CdreDefaultInstance.CdrFormat, _ = c.GetString("cdre", "cdr_format") } diff --git a/config/config_test.go b/config/config_test.go index 68b3d0911..1784002ef 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -84,6 +84,7 @@ func TestDefaults(t *testing.T) { eCfg.CDRSExtraFields = []*utils.RSRField{} eCfg.CDRSMediator = "" eCfg.CDRStatsEnabled = false + eCfg.CDRStatConfig = &CdrStatsConfig{Id: utils.DEFAULT_RUNID, QueueLength: 50, TimeWindow: time.Duration(1) * time.Hour, Metrics: []string{"ASR", "ACD", "ACC"}} eCfg.CdrcEnabled = false eCfg.CdrcCdrs = utils.INTERNAL eCfg.CdrcRunDelay = time.Duration(0) @@ -218,6 +219,11 @@ func TestConfigFromFile(t *testing.T) { eCfg.CDRSExtraFields = []*utils.RSRField{&utils.RSRField{Id: "test"}} eCfg.CDRSMediator = "test" eCfg.CDRStatsEnabled = true + eCfg.CDRStatConfig = &CdrStatsConfig{Id: utils.DEFAULT_RUNID, QueueLength: 99, TimeWindow: time.Duration(99) * time.Second, + Metrics: []string{"test"}, TOR: []string{"test"}, CdrHost: []string{"test"}, CdrSource: []string{"test"}, ReqType: []string{"test"}, Direction: []string{"test"}, + Tenant: []string{"test"}, Category: []string{"test"}, Account: []string{"test"}, Subject: []string{"test"}, DestinationPrefix: []string{"test"}, + UsageInterval: []time.Duration{time.Duration(99) * time.Second}, + MediationRunIds: []string{"test"}, RatedAccount: []string{"test"}, RatedSubject: []string{"test"}, CostInterval: []float64{99.0}} eCfg.CDRSStats = "test" eCfg.CdreDefaultInstance = &CdreConfig{ CdrFormat: "test", diff --git a/config/test_data.txt b/config/test_data.txt index 16910e06d..cfa0d371f 100644 --- a/config/test_data.txt +++ b/config/test_data.txt @@ -92,7 +92,7 @@ enabled = true # Start the CDR stats service: . queue_length = 99 # Number of items in the stats buffer time_window = 99 # Will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow metrics = test # Stat metric ids to build -setup_intervals =test # Filter on CDR SetupTime +setup_interval = # Filter on CDR SetupTime tors = test # Filter on CDR TOR fields cdr_hosts= test # Filter on CDR CdrHost fields cdr_sources = test # Filter on CDR CdrSource fields @@ -103,11 +103,11 @@ categories = test # Filter on CDR Category fields accounts = test # Filter on CDR Account fields subjects = test # Filter on CDR Subject fields destination_prefixes = test # Filter on CDR Destination prefixes -usage_intervals = test # Filter on CDR Usage -mediation_runs = test # Filter on CDR MediationRunId fields +usage_interval = 99 # Filter on CDR Usage +mediation_run_ids = test # Filter on CDR MediationRunId fields rated_accounts = test # Filter on CDR RatedAccount fields rated_subjects = test # Filter on CDR RatedSubject fields -cost_intervals = test # Filter on CDR Cost +cost_intervals = 99 # Filter on CDR Cost [session_manager] enabled = true # Starts SessionManager service: . diff --git a/data/conf/cgrates.cfg b/data/conf/cgrates.cfg index 15b07c24b..9ae6d61ce 100644 --- a/data/conf/cgrates.cfg +++ b/data/conf/cgrates.cfg @@ -95,7 +95,7 @@ # queue_length = 50 # Number of items in the stats buffer # time_window = 1h # Will only keep the CDRs who's call setup time is not older than time.Now()-TimeWindow # metrics = ASR, ACD, ACC # Stat metric ids to build -# setup_intervals = # Filter on CDR SetupTime +# setup_interval = # Filter on CDR SetupTime # tors = # Filter on CDR TOR fields # cdr_hosts= # Filter on CDR CdrHost fields # cdr_sources = # Filter on CDR CdrSource fields @@ -106,8 +106,8 @@ # accounts = # Filter on CDR Account fields # subjects = # Filter on CDR Subject fields # destination_prefixes = # Filter on CDR Destination prefixes -# usage_intervals = # Filter on CDR Usage -# mediation_runs = # Filter on CDR MediationRunId fields +# usage_interval = # Filter on CDR Usage +# mediation_run_ids = # Filter on CDR MediationRunId fields # rated_accounts = # Filter on CDR RatedAccount fields # rated_subjects = # Filter on CDR RatedSubject fields # cost_intervals = # Filter on CDR Cost diff --git a/engine/stats_metrics.go b/engine/stats_metrics.go index 007543f8e..cf6a0dc86 100644 --- a/engine/stats_metrics.go +++ b/engine/stats_metrics.go @@ -26,9 +26,9 @@ type Metric interface { GetValue() float64 } -const ASR = "asr" -const ACD = "acd" -const ACC = "acc" +const ASR = "ASR" +const ACD = "ACD" +const ACC = "ACC" func CreateMetric(metric string) Metric { switch metric {