mirror of
https://github.com/cgrates/cgrates.git
synced 2026-02-11 18:16:24 +05:00
Update reply to include metrics per exporter
This commit is contained in:
committed by
Dan Christian Bogos
parent
8cc0af4981
commit
25933e9922
@@ -29,8 +29,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/cgrates/cgrates/ees"
|
||||
|
||||
"github.com/cgrates/cgrates/config"
|
||||
"github.com/cgrates/cgrates/engine"
|
||||
"github.com/cgrates/cgrates/guardian"
|
||||
@@ -1886,8 +1884,11 @@ func (apierSv1 *APIerSv1) ExportCDRs(args *utils.ArgExportCDRs, reply *map[strin
|
||||
for exporterID := range rplyCdr {
|
||||
(*reply)[utils.ExporterIDs] = append((*reply)[utils.ExporterIDs].([]string), exporterID)
|
||||
}
|
||||
} else if *reply, err = ees.MergeEEMetrics(rplyCdr); err != nil {
|
||||
return
|
||||
} else {
|
||||
for exporterID, metrics := range rplyCdr {
|
||||
(*reply)[exporterID] = metrics
|
||||
}
|
||||
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -193,14 +193,31 @@ func testEEsExportCDRs(t *testing.T) {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
if rply["FirstExpOrderID"] != 1.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1.0, rply["FirstExpOrderID"])
|
||||
} else if rply["LastExpOrderID"] != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, rply["LastExpOrderID"])
|
||||
} else if rply["NumberOfEvents"] != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, rply["NumberOfEvents"])
|
||||
} else if rply["TotalCost"] != 4.04 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.04, rply["TotalCost"])
|
||||
if len(rply) != 1 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1, len(rply))
|
||||
} else {
|
||||
val, _ := rply["CSVExporter"]
|
||||
for k, v := range val.(map[string]interface{}) {
|
||||
switch k {
|
||||
case utils.FirstExpOrderID:
|
||||
if v != 1.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1.0, v)
|
||||
}
|
||||
case utils.LastExpOrderID:
|
||||
if v != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, v)
|
||||
}
|
||||
case utils.NumberOfEvents:
|
||||
if v != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, v)
|
||||
}
|
||||
case utils.TotalCost:
|
||||
if v != 4.04 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.04, v)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,9 +235,9 @@ func testEEsVerifyExports(t *testing.T) {
|
||||
if len(files) != 1 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1, len(files))
|
||||
}
|
||||
eCnt := "Cdr1,*raw,*voice,OriginCDR1,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,10000000000,1.01\n" +
|
||||
"Cdr2,*raw,*voice,OriginCDR2,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,5000000000,1.01\n" +
|
||||
"Cdr3,*raw,*voice,OriginCDR3,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,30000000000,1.01\n" +
|
||||
eCnt := "Cdr1,*raw,*voice,OriginCDR1,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,10,1.01\n" +
|
||||
"Cdr2,*raw,*voice,OriginCDR2,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,5,1.01\n" +
|
||||
"Cdr3,*raw,*voice,OriginCDR3,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,30,1.01\n" +
|
||||
"Cdr4,*raw,*voice,OriginCDR4,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,0,1.01\n"
|
||||
if outContent1, err := ioutil.ReadFile(files[0]); err != nil {
|
||||
t.Error(err)
|
||||
@@ -240,14 +257,33 @@ func testEEsExportCDRsMultipleExporters(t *testing.T) {
|
||||
t.Error("Unexpected error: ", err.Error())
|
||||
}
|
||||
time.Sleep(2 * time.Second)
|
||||
if rply["FirstExpOrderID"] != 1.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1.0, rply["FirstExpOrderID"])
|
||||
} else if rply["LastExpOrderID"] != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, rply["LastExpOrderID"])
|
||||
} else if rply["NumberOfEvents"] != 8.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 8.0, rply["NumberOfEvents"])
|
||||
} else if rply["TotalCost"] != 8.08 {
|
||||
t.Errorf("Expected %+v, received: %+v", 8.08, rply["TotalCost"])
|
||||
if len(rply) != 2 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1, len(rply))
|
||||
} else {
|
||||
for _, expID := range []string{"CSVExporter", "CSVExporter2"} {
|
||||
val, _ := rply[expID]
|
||||
for k, v := range val.(map[string]interface{}) {
|
||||
switch k {
|
||||
case utils.FirstExpOrderID:
|
||||
if v != 1.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1.0, v)
|
||||
}
|
||||
case utils.LastExpOrderID:
|
||||
if v != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, v)
|
||||
}
|
||||
case utils.NumberOfEvents:
|
||||
if v != 4.0 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.0, v)
|
||||
}
|
||||
case utils.TotalCost:
|
||||
if v != 4.04 {
|
||||
t.Errorf("Expected %+v, received: %+v", 4.04, v)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -265,9 +301,9 @@ func testEEsVerifyExportsMultipleExporters(t *testing.T) {
|
||||
if len(files) != 1 {
|
||||
t.Errorf("Expected %+v, received: %+v", 1, len(files))
|
||||
}
|
||||
eCnt := "Cdr1,*raw,*voice,OriginCDR1,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,10000000000,1.01\n" +
|
||||
"Cdr2,*raw,*voice,OriginCDR2,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,5000000000,1.01\n" +
|
||||
"Cdr3,*raw,*voice,OriginCDR3,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,30000000000,1.01\n" +
|
||||
eCnt := "Cdr1,*raw,*voice,OriginCDR1,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,10,1.01\n" +
|
||||
"Cdr2,*raw,*voice,OriginCDR2,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,5,1.01\n" +
|
||||
"Cdr3,*raw,*voice,OriginCDR3,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,30,1.01\n" +
|
||||
"Cdr4,*raw,*voice,OriginCDR4,*none,cgrates.org,call,1001,1001,+4986517174963,2018-10-04T15:03:10Z,2018-10-04T15:03:10Z,0,1.01\n"
|
||||
if outContent1, err := ioutil.ReadFile(files[0]); err != nil {
|
||||
t.Error(err)
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -107,7 +107,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -133,7 +133,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -111,7 +111,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -137,7 +137,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -109,7 +109,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
},
|
||||
@@ -135,7 +135,7 @@
|
||||
{"tag": "Destination", "path": "*exp.Destination", "type": "*variable", "value": "~*req.Destination"},
|
||||
{"tag": "SetupTime", "path": "*exp.SetupTime", "type": "*variable", "value": "~*req.SetupTime{*time_string}" },
|
||||
{"tag": "AnswerTime", "path": "*exp.AnswerTime", "type": "*variable", "value": "~*req.AnswerTime{*time_string}"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage"},
|
||||
{"tag": "Usage", "path": "*exp.Usage", "type": "*variable", "value": "~*req.Usage{*duration_seconds}"},
|
||||
{"tag": "Cost", "path": "*exp.Cost", "type": "*variable", "value": "~*req.Cost{*round:4}"},
|
||||
],
|
||||
}
|
||||
|
||||
121
ees/ees.go
121
ees/ees.go
@@ -245,8 +245,21 @@ func (eeS *EventExporterS) V1ProcessEvent(cgrEv *utils.CGREventWithIDs, rply *ma
|
||||
|
||||
*rply = make(map[string]map[string]interface{})
|
||||
metricMapLock.Lock()
|
||||
for k, v := range metricsMap {
|
||||
(*rply)[k] = v
|
||||
for exporterID, metrics := range metricsMap {
|
||||
(*rply)[exporterID] = make(map[string]interface{})
|
||||
for key, val := range metrics {
|
||||
switch key {
|
||||
case utils.PositiveExports, utils.NegativeExports:
|
||||
slsVal, canCast := val.(utils.StringSet)
|
||||
if !canCast {
|
||||
return fmt.Errorf("cannot cast to map[string]interface{} %+v for positive exports", val)
|
||||
}
|
||||
(*rply)[exporterID][key] = slsVal.AsSlice()
|
||||
default:
|
||||
(*rply)[exporterID][key] = val
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
metricMapLock.Unlock()
|
||||
return
|
||||
@@ -330,107 +343,3 @@ func updateEEMetrics(dc utils.MapStorage, ev engine.MapEvent, timezone string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func MergeEEMetrics(dc map[string]map[string]interface{}) (reply map[string]interface{}, err error) {
|
||||
positiveExp := make(utils.StringSet)
|
||||
negativeExp := make(utils.StringSet)
|
||||
reply = map[string]interface{}{
|
||||
utils.PositiveExports: positiveExp,
|
||||
utils.NegativeExports: negativeExp,
|
||||
}
|
||||
for _, metrics := range dc {
|
||||
for k, v := range metrics {
|
||||
switch k {
|
||||
case utils.NumberOfEvents:
|
||||
val, err := utils.IfaceAsTInt64(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else {
|
||||
reply[k] = reply[k].(int64) + val
|
||||
}
|
||||
case utils.PositiveExports:
|
||||
val, canCast := v.(map[string]interface{})
|
||||
if !canCast {
|
||||
return nil, fmt.Errorf("cannot cast to map[string]interface{} %+v for positive exports", v)
|
||||
}
|
||||
for pos := range val {
|
||||
positiveExp.Add(pos)
|
||||
}
|
||||
case utils.NegativeExports:
|
||||
val, canCast := v.(map[string]interface{})
|
||||
if !canCast {
|
||||
return nil, fmt.Errorf("cannot cast to map[string]interface{} %+v for negative exports", v)
|
||||
}
|
||||
for neg := range val {
|
||||
negativeExp.Add(neg)
|
||||
}
|
||||
case utils.FirstEventATime:
|
||||
val, err := utils.IfaceAsTime(v, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else if val.Before(reply[k].(time.Time)) {
|
||||
reply[k] = val
|
||||
}
|
||||
case utils.LastEventATime:
|
||||
val, err := utils.IfaceAsTime(v, config.CgrConfig().GeneralCfg().DefaultTimezone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else if val.After(reply[k].(time.Time)) {
|
||||
reply[k] = val
|
||||
}
|
||||
case utils.FirstExpOrderID:
|
||||
val, err := utils.IfaceAsTInt64(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else if reply[k].(int64) > val {
|
||||
reply[k] = val
|
||||
}
|
||||
case utils.LastExpOrderID:
|
||||
val, err := utils.IfaceAsTInt64(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else if reply[k].(int64) < val {
|
||||
reply[k] = val
|
||||
}
|
||||
case utils.TotalCost:
|
||||
val, err := utils.IfaceAsFloat64(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else {
|
||||
reply[k] = reply[k].(float64) + val
|
||||
}
|
||||
case utils.TotalDuration, utils.TotalSMSUsage,
|
||||
utils.TotalMMSUsage, utils.TotalGenericUsage,
|
||||
utils.TotalDataUsage:
|
||||
val, err := utils.IfaceAsDuration(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, has := reply[k]; !has {
|
||||
reply[k] = val
|
||||
} else {
|
||||
reply[k] = reply[k].(time.Duration) + val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user