import (
"encoding/json"
+ "fmt"
"io"
"io/ioutil"
"os"
ReportingEntityID: readSystemUUID(),
MaxSize: 2000000,
NfNamingCode: getNFNamingCode(),
- NfcNamingCodes: []NfcNamingCode{},
- RetryInterval: time.Second * 5,
- MaxMissed: 2,
+ NfcNamingCodes: []NfcNamingCode{},
+ RetryInterval: time.Second * 5,
+ MaxMissed: 2,
},
Measurement: MeasurementConfiguration{
// Domain abbreviation has to be set to “Mvfs” for VES 5.3,
// AppMetricsStruct contains xapplication metrics definition
type AppMetricsStruct struct {
+ MoId string
+ MeasType string
+ MeasId string
+ MeasInterval string
ObjectName string
ObjectInstance string
- MeasId string
- MeasObject string
+ CounterId string
}
// AppMetrics contains metrics definitions for all Xapps
}
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)
- measObject, objectOk := m.(map[string]interface{})["object"].(string)
+ measInterval, measIntervalOk := m.(map[string]interface{})["measInterval"].(string)
metrics, metricsOk := m.(map[string]interface{})["metrics"]
- if !metricsOk || !measIdOk || !objectOk {
- logger.Info("No metrics found for measId=%s Object=%s", measId, measObject)
+ 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
}
- parseMetricsRules(metrics.([]interface{}), appMetrics, measId, measObject)
+ 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
// 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, measId, measObject string) AppMetrics {
+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)
- if !alreadyFound && objectNameOk && objectInstanceOk {
- appMetrics[name] = AppMetricsStruct{objectName, objectInstance, measId, measObject}
- logger.Info("parsed counter %s %s %s", name, objectName, objectInstance)
+ 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) {
+func getRules(vespaconf *VESAgentConfiguration, xAppConfig []byte) bool {
makeRule := func(expr string, value AppMetricsStruct) MetricRule {
return MetricRule{
Target: "AdditionalObjects",
Expr: expr,
- ObjectInstance: value.ObjectInstance,
+ ObjectInstance: fmt.Sprintf("%s:%s", value.ObjectInstance, value.CounterId),
ObjectName: value.ObjectName,
ObjectKeys: []Label{
- Label{
- Name: "ricComponentName",
- Expr: "'{{.labels.kubernetes_name}}'",
- },
- Label{
- Name: "measObject",
- Expr: value.MeasObject,
- },
- Label{
- Name: "measId",
- Expr: value.MeasId,
- },
+ {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},
},
}
}
if len(vespaconf.Measurement.Prometheus.Rules.Metrics) == 0 {
logger.Info("vespa config with empty metrics")
}
+
+ return len(vespaconf.Measurement.Prometheus.Rules.Metrics) > 0
}
func getCollectorConfiguration(vespaconf *VESAgentConfiguration) {
vespaconf.PrimaryCollector.ServerRoot = os.Getenv("VESMGR_PRICOLLECTOR_SERVERROOT")
vespaconf.PrimaryCollector.Topic = os.Getenv("VESMGR_PRICOLLECTOR_TOPIC")
portStr := os.Getenv("VESMGR_PRICOLLECTOR_PORT")
+
if portStr == "" {
vespaconf.PrimaryCollector.Port = 8443
} else {
port, _ := strconv.Atoi(portStr)
vespaconf.PrimaryCollector.Port = port
}
+
secureStr := os.Getenv("VESMGR_PRICOLLECTOR_SECURE")
if secureStr == "true" {
vespaconf.PrimaryCollector.Secure = true
func createVespaConfig(writer io.Writer, xAppStatus []byte) {
vespaconf := basicVespaConf()
+
getRules(&vespaconf, xAppStatus)
+
getCollectorConfiguration(&vespaconf)
+
err := yaml.NewEncoder(writer).Encode(vespaconf)
if err != nil {
logger.Error("Cannot write vespa conf file: %s", err.Error())
func TestParseMetricsRules(t *testing.T) {
metricsJSON := `{"metrics": [
- { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
- { "name": "ricxapp_RMR_ReceiveError", "objectName": "ricxappRMRReceiveErrorCounter", "objectInstance": "ricxappRMRReceiveError" },
- { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" },
- { "name": "ricxapp_RMR_TransmitError", "objectName": "ricxappRMRTransmitErrorCounter", "objectInstance": "ricxappRMRTransmitError" },
- { "name": "ricxapp_SDL_Stored", "objectName": "ricxappSDLStoredCounter", "objectInstance": "ricxappSDLStored" },
- { "name": "ricxapp_SDL_StoreError", "objectName": "ricxappSDLStoreErrorCounter", "objectInstance": "ricxappSDLStoreError" } ]}`
+ { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
+ { "name": "ricxapp_RMR_ReceiveError", "objectName": "ricxappRMRReceiveErrorCounter", "objectInstance": "ricxappRMRReceiveError", "counterId": "0011" },
+ { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" },
+ { "name": "ricxapp_RMR_TransmitError", "objectName": "ricxappRMRTransmitErrorCounter", "objectInstance": "ricxappRMRTransmitError", "counterId": "0011" },
+ { "name": "ricxapp_SDL_Stored", "objectName": "ricxappSDLStoredCounter", "objectInstance": "ricxappSDLStored", "counterId": "0011" },
+ { "name": "ricxapp_SDL_StoreError", "objectName": "ricxappSDLStoreErrorCounter", "objectInstance": "ricxappSDLStoreError", "counterId": "0011" } ]}`
appMetrics := make(AppMetrics)
m := metricsStringToInterfaceArray(metricsJSON)
- appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Len(t, appMetrics, 6)
assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
assert.Equal(t, "ricxappRMRTransmitErrorCounter", appMetrics["ricxapp_RMR_TransmitError"].ObjectName)
appMetrics := make(AppMetrics)
metricsJSON := `{"metrics": []`
m := metricsStringToInterfaceArray(metricsJSON)
- appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Empty(t, appMetrics)
}
func TestParseMetricsRulesAdditionalFields(t *testing.T) {
appMetrics := make(AppMetrics)
metricsJSON := `{"metrics": [
- { "additionalField": "valueIgnored", "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" }]}`
+ { "additionalField": "valueIgnored", "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" }]}`
m := metricsStringToInterfaceArray(metricsJSON)
- appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Len(t, appMetrics, 1)
assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
func TestParseMetricsRulesMissingFields(t *testing.T) {
appMetrics := make(AppMetrics)
metricsJSON := `{"metrics": [
- { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
+ { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
{ "name": "ricxapp_RMR_ReceiveError", "objectInstance": "ricxappRMRReceiveError" },
- { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+ { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
m := metricsStringToInterfaceArray(metricsJSON)
- appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Len(t, appMetrics, 2)
assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
assert.Equal(t, "ricxappRMRTransmittedCounter", appMetrics["ricxapp_RMR_Transmitted"].ObjectName)
func TestParseMetricsRulesDuplicateDefinitionIsIgnored(t *testing.T) {
appMetrics := make(AppMetrics)
metricsJSON := `{"metrics": [
- { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" },
- { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounterXXX", "objectInstance": "ricxappRMRReceivedXXX" },
- { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+ { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" },
+ { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounterXXX", "objectInstance": "ricxappRMRReceivedXXX", "counterId": "0011" },
+ { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
m := metricsStringToInterfaceArray(metricsJSON)
- appMetrics = parseMetricsRules(m, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Len(t, appMetrics, 2)
assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
func TestParseMetricsRulesIncrementalFillOfAppMetrics(t *testing.T) {
appMetrics := make(AppMetrics)
metricsJSON1 := `{"metrics": [
- { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived" }]}`
+ { "name": "ricxapp_RMR_Received", "objectName": "ricxappRMRreceivedCounter", "objectInstance": "ricxappRMRReceived", "counterId": "0011" }]}`
metricsJSON2 := `{"metrics": [
- { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted" }]}`
+ { "name": "ricxapp_RMR_Transmitted", "objectName": "ricxappRMRTransmittedCounter", "objectInstance": "ricxappRMRTransmitted", "counterId": "0011" }]}`
m1 := metricsStringToInterfaceArray(metricsJSON1)
m2 := metricsStringToInterfaceArray(metricsJSON2)
- appMetrics = parseMetricsRules(m1, appMetrics, "M1234", "App-1")
- appMetrics = parseMetricsRules(m2, appMetrics, "M1234", "App-1")
+ appMetrics = parseMetricsRules(m1, appMetrics, "SEP/XAPP", "X2", "1234", "60")
+ appMetrics = parseMetricsRules(m2, appMetrics, "SEP/XAPP", "X2", "1234", "60")
assert.Len(t, appMetrics, 2)
assert.Equal(t, "ricxappRMRreceivedCounter", appMetrics["ricxapp_RMR_Received"].ObjectName)
assert.Equal(t, "ricxappRMRReceived", appMetrics["ricxapp_RMR_Received"].ObjectInstance)
return emptyConfig, errors.New(resp.Status)
}
-func queryConf() ([]byte, error) {
- return queryXAppsConfig("http://"+appmgrDomain+":"+appmgrPort+appmgrXAppConfigPath,
- 10*time.Second)
+func queryConf() (appConfig []byte, err error) {
+ for i := 0; i < 10; i++ {
+ appConfig, err = queryXAppsConfig("http://"+appmgrDomain+":"+appmgrPort+appmgrXAppConfigPath, 10*time.Second)
+ if len(appConfig) > 0 {
+ break
+ }
+ time.Sleep(5 * time.Second)
+ }
+ return appConfig, err
}
func (vesmgr *VesMgr) emptyNotificationsChannel() {
// Run the vesmgr process main loop
func (vesmgr *VesMgr) Run() {
logger.Info("vesmgr main loop ready")
+
vesmgr.httpServer.start(vesmgrXappNotifPath, vesmgr.chXAppNotifications, vesmgr.chSupervision)
+
vesmgr.subscribeXAppNotifications()
+
vesmgr.waitSubscriptionLoop()
+
xappConfig, _ := queryConf()
+
createConf(vespaConfigFile, xappConfig)
+
vesmgr.startVesagent()
for {
vesmgr.servRequest()
# The Jenkins job uses this string for the tag in the image name
# for example nexus3.o-ran-sc.org:10004/my-image-name:0.0.1
---
-tag: 0.5.0
+tag: 0.5.1
},
"measurements": [
{
- "measId": "M9001",
- "object": "XAPP-xApp1",
+ "moId": "SEP-12/XAPP-1",
+ "measType": "X2",
+ "measId": "9001",
+ "measInterval": "60",
"metrics": [
{
- "description": "Example counter 1",
- "enabled": true,
"name": "App1ExampleCounterOne",
- "type": "counter",
"objectName": "App1ExampleCounterOneObject",
- "objectInstance": "App1ExampleCounterOneObjectInstance"
+ "objectInstance": "App1ExampleCounterOneObjectInstance",
+ "counterId": "0011",
+ "type": "counter",
+ "description": "Example counter 1"
},
{
- "description": "Example counter 2",
- "enabled": true,
"name": "App1ExampleCounterTwo",
- "type": "counter",
"objectName": "App1ExampleCounterTwoObject",
- "objectInstance": "App1ExampleCounterTwoObjectInstance"
+ "objectInstance": "App1ExampleCounterTwoObjectInstance",
+ "counterId": "0012",
+ "type": "counter",
+ "description": "Example counter 2"
}
]
}
},
"measurements": [
{
- "measId": "M9001",
- "object": "XAPP-xApp2",
+ "moId": "SEP-12/XAPP-2",
+ "measType": "X2",
+ "measId": "9002",
+ "measInterval": "60",
"metrics": [
{
- "description": "Example counter",
- "enabled": true,
"name": "App2ExampleCounterOne",
- "type": "counter",
"objectName": "App2ExampleCounterOneObject",
- "objectInstance": "App2ExampleCounterOneObjectInstance"
+ "objectInstance": "App2ExampleCounterOneObjectInstance",
+ "counterId": "0021",
+ "type": "counter",
+ "description": "Example counter 1"
},
{
- "description": "Another example counter",
- "enabled": true,
"name": "App2ExampleCounterTwo",
- "type": "counter",
"objectName": "App2ExampleCounterTwoObject",
- "objectInstance": "App2ExampleCounterTwoObjectInstance"
+ "objectInstance": "App2ExampleCounterTwoObjectInstance",
+ "counterId": "0022",
+ "type": "counter",
+ "description": "Example counter 2"
}
]
}