+// AppMetricsStruct contains xapplication metrics definition
+type AppMetricsStruct struct {
+ MoId string
+ MeasType string
+ MeasId string
+ MeasInterval string
+ ObjectName string
+ ObjectInstance string
+ CounterId string
+}
+
+// AppMetrics contains metrics definitions for all Xapps
+type AppMetrics map[string]AppMetricsStruct
+
+// Parses the metrics data from an array of bytes, which is expected to contain a JSON
+// array with structs of the following format:
+//
+// { ...
+// "config" : {
+// "measurements": [
+// {
+// "metrics": [
+// { "name": "...", "objectName": "...", "objectInstamce": "..." },
+// ...
+// ]
+// }
+// ...
+// ]
+// }
+// }
+func parseMetricsFromXAppDescriptor(descriptor []byte, appMetrics AppMetrics) AppMetrics {
+ var desc []map[string]interface{}
+ json.Unmarshal(descriptor, &desc)
+
+ for _, app := range desc {
+ config, configOk := app["config"]
+ if !configOk {
+ logger.Info("No xApp config found!")
+ continue
+ }
+ measurements, measurementsOk := config.(map[string]interface{})["measurements"]
+ if !measurementsOk {
+ logger.Info("No xApp metrics found!")
+ continue
+ }
+
+ for _, m := range measurements.([]interface{}) {
+ moId, moIdOk := m.(map[string]interface{})["moId"].(string)
+ measType, measTypeOk := m.(map[string]interface{})["measType"].(string)
+ measId, measIdOk := m.(map[string]interface{})["measId"].(string)
+ measInterval, measIntervalOk := m.(map[string]interface{})["measInterval"].(string)
+ metrics, metricsOk := m.(map[string]interface{})["metrics"]
+ if !metricsOk || !measTypeOk || !measIdOk || !moIdOk || !measIntervalOk {
+ logger.Info("No metrics found for moId=%s measType=%s measId=%s measInterval=%s", moId, measId, measType, measInterval)
+ continue
+ }
+ logger.Info("Parsed measurement: moId=%s type=%s id=%s interval=%s", moId, measType, measId, measInterval)
+
+ parseMetricsRules(metrics.([]interface{}), appMetrics, moId, measType, measId, measInterval)
+ }
+ }
+ return appMetrics
+}
+
+// Parses the metrics data from an array of interfaces, which are expected to be maps
+// of the following format:
+// { "name": xxx, "objectName": yyy, "objectInstance": zzz }
+// Entries, which do not have all the necessary fields, are ignored.
+func parseMetricsRules(metricsMap []interface{}, appMetrics AppMetrics, moId, measType, measId, measInterval string) AppMetrics {
+ for _, element := range metricsMap {
+ name, nameOk := element.(map[string]interface{})["name"].(string)
+ if nameOk {
+ _, alreadyFound := appMetrics[name]
+ objectName, objectNameOk := element.(map[string]interface{})["objectName"].(string)
+ objectInstance, objectInstanceOk := element.(map[string]interface{})["objectInstance"].(string)
+ counterId, counterIdOk := element.(map[string]interface{})["counterId"].(string)
+ if !alreadyFound && objectNameOk && objectInstanceOk && counterIdOk {
+ appMetrics[name] = AppMetricsStruct{moId, measType, measId, measInterval, objectName, objectInstance, counterId}
+ logger.Info("Parsed counter name=%s %s/%s M%sC%s", name, objectName, objectInstance, measId, counterId)
+ }
+ if alreadyFound {
+ logger.Info("skipped duplicate counter %s", name)
+ }
+ }
+ }
+ return appMetrics
+}
+
+func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) bool {
+ makeRule := func(expr string, value AppMetricsStruct) MetricRule {
+ return MetricRule{
+ Target: "AdditionalObjects",
+ Expr: expr,
+ ObjectInstance: fmt.Sprintf("%s:%s", value.ObjectInstance, value.CounterId),
+ ObjectName: value.ObjectName,
+ ObjectKeys: []Label{
+ {Name: "ricComponentName", Expr: "'{{.labels.kubernetes_name}}'"},
+ {Name: "moId", Expr: value.MoId},
+ {Name: "measType", Expr: value.MeasType},
+ {Name: "measId", Expr: value.MeasId},
+ {Name: "measInterval", Expr: value.MeasInterval},