Skip to content

Commit

Permalink
feat: add NRF registrations, subcriptions and discovery metrics (#128)
Browse files Browse the repository at this point in the history
* feat: add NRF metrics counters

Signed-off-by: Dario Faccin <[email protected]>

* revert deregister stats

Signed-off-by: Dario Faccin <[email protected]>

* Revert "revert deregister stats"

This reverts commit 1e4bcd3.

Signed-off-by: Dario Faccin <[email protected]>

* chore: add NfInstances metrics

Signed-off-by: Dario Faccin <[email protected]>

* improve remove subscription data

Signed-off-by: Dario Faccin <[email protected]>

* improve update subscription data

Signed-off-by: Dario Faccin <[email protected]>

* fix: avoid accessing empty array on NF deregistration

Signed-off-by: Dario Faccin <[email protected]>

* improve query type name for subscription removal

Signed-off-by: Dario Faccin <[email protected]>

* improve NF type handling in NF discovery procedure

Signed-off-by: Dario Faccin <[email protected]>

* address review comments:
* do not panic on stats initialization failure
* fix wrong outcome in NF discovery stats

Signed-off-by: Dario Faccin <[email protected]>

* Update producer/nf_discovery.go

Co-authored-by: ajaythakurintel <[email protected]>
Signed-off-by: Arrobo, Gabriel <[email protected]>

---------

Signed-off-by: Dario Faccin <[email protected]>
Signed-off-by: Arrobo, Gabriel <[email protected]>
Co-authored-by: Arrobo, Gabriel <[email protected]>
Co-authored-by: ajaythakurintel <[email protected]>
  • Loading branch information
3 people authored Oct 1, 2024
1 parent 5846563 commit 3df6b3c
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 16 deletions.
63 changes: 63 additions & 0 deletions metrics/telemetry.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,76 @@ import (
"net/http"

"github.com/omec-project/nrf/logger"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)

// NrfStats captures NRF stats
type NrfStats struct {
nrfRegistrations *prometheus.CounterVec
nrfSubscriptions *prometheus.CounterVec
nrfNfInstances *prometheus.CounterVec
}

var nrfStats *NrfStats

func initNrfStats() *NrfStats {
return &NrfStats{
nrfRegistrations: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "nrf_registrations",
Help: "Counter of total NRF registration events",
}, []string{"query_type", "nf_type", "result"}),
nrfSubscriptions: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "nrf_subscriptions",
Help: "Counter of total NRF subscription events",
}, []string{"query_type", "request_nf_type", "result"}),
nrfNfInstances: prometheus.NewCounterVec(prometheus.CounterOpts{
Name: "nrf_nf_instances",
Help: "Counter of total NRF instances queries",
}, []string{"request_nf_type", "target_nf_type", "result"}),
}
}

func (ps *NrfStats) register() error {
if err := prometheus.Register(ps.nrfRegistrations); err != nil {
return err
}
if err := prometheus.Register(ps.nrfSubscriptions); err != nil {
return err
}
if err := prometheus.Register(ps.nrfNfInstances); err != nil {
return err
}
return nil
}

func init() {
nrfStats = initNrfStats()

if err := nrfStats.register(); err != nil {
logger.InitLog.Errorln("NRF Stats register failed")
}
}

// InitMetrics initialises NRF metrics
func InitMetrics() {
http.Handle("/metrics", promhttp.Handler())
if err := http.ListenAndServe(":8080", nil); err != nil {
logger.InitLog.Errorf("Could not open metrics port: %v", err)
}
}

// IncrementNrfRegistrationsStats increments number of total NRF registrations
func IncrementNrfRegistrationsStats(queryType, nfType, result string) {
nrfStats.nrfRegistrations.WithLabelValues(queryType, nfType, result).Inc()
}

// IncrementNrfSubscriptionsStats increments number of total NRF subscriptions
func IncrementNrfSubscriptionsStats(queryType, requestNfType, result string) {
nrfStats.nrfSubscriptions.WithLabelValues(queryType, requestNfType, result).Inc()
}

// IncrementNrfNfInstancesStats increments number of total NRF queries
func IncrementNrfNfInstancesStats(requestNfType, targetNfType, result string) {
nrfStats.nrfNfInstances.WithLabelValues(requestNfType, targetNfType, result).Inc()
}
17 changes: 17 additions & 0 deletions producer/nf_discovery.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package producer

import (
"encoding/json"
"fmt"
"math/big"
"net/http"
"net/url"
Expand All @@ -21,6 +22,7 @@ import (
"github.com/omec-project/nrf/context"
"github.com/omec-project/nrf/dbadapter"
"github.com/omec-project/nrf/logger"
stats "github.com/omec-project/nrf/metrics"
"github.com/omec-project/nrf/util"
"github.com/omec-project/openapi/models"
"github.com/omec-project/util/httpwrapper"
Expand All @@ -31,18 +33,22 @@ func HandleNFDiscoveryRequest(request *httpwrapper.Request) *httpwrapper.Respons
logger.DiscoveryLog.Infoln("Handle NFDiscoveryRequest")

response, problemDetails := NFDiscoveryProcedure(request.Query)
requesterNfType, targetNfType := GetRequesterAndTargetNfTypeGivenQueryParameters(request.Query)
// Send Response
// step 4: process the return value from step 3
if response != nil {
// status code is based on SPEC, and option headers
stats.IncrementNrfNfInstancesStats(requesterNfType, targetNfType, "SUCCESS")
return httpwrapper.NewResponse(http.StatusOK, nil, response)
} else if problemDetails != nil {
stats.IncrementNrfNfInstancesStats(requesterNfType, targetNfType, "FAILURE")
return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails)
}
problemDetails = &models.ProblemDetails{
Status: http.StatusForbidden,
Cause: "UNSPECIFIED",
}
stats.IncrementNrfNfInstancesStats(requesterNfType, targetNfType, "FAILURE")
return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails)
}

Expand Down Expand Up @@ -2253,3 +2259,14 @@ func complexQueryFilterSubprocess(queryParameters map[string]*AtomElem, complexQ

return filter
}

func GetRequesterAndTargetNfTypeGivenQueryParameters(queryParameters url.Values) (requesterNfType, targetNfType string) {
requesterNfType, targetNfType = "UNKNOWN_NF", "UNKNOWN_NF"
if queryParameters["requester-nf-type"] != nil {
requesterNfType = fmt.Sprint(queryParameters["requester-nf-type"][0])
}
if queryParameters["target-nf-type"] != nil {
targetNfType = fmt.Sprint(queryParameters["target-nf-type"][0])
}
return requesterNfType, targetNfType
}
76 changes: 60 additions & 16 deletions producer/nf_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/omec-project/nrf/dbadapter"
"github.com/omec-project/nrf/factory"
"github.com/omec-project/nrf/logger"
stats "github.com/omec-project/nrf/metrics"
"github.com/omec-project/nrf/util"
"github.com/omec-project/openapi/Nnrf_NFManagement"
"github.com/omec-project/openapi/models"
Expand All @@ -30,12 +31,15 @@ func HandleNFDeregisterRequest(request *httpwrapper.Request) *httpwrapper.Respon
logger.ManagementLog.Infoln("Handle NFDeregisterRequest")
nfInstanceId := request.Params["nfInstanceID"]

problemDetails := NFDeregisterProcedure(nfInstanceId)
nfType, problemDetails := NFDeregisterProcedure(nfInstanceId)

if problemDetails != nil {
logger.ManagementLog.Infoln("[NRF] Dergeister Success")
logger.ManagementLog.Traceln("deregister failure")
stats.IncrementNrfRegistrationsStats("deregister", nfType, "FAILURE")
return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails)
} else {
logger.ManagementLog.Traceln("deregister Success")
stats.IncrementNrfRegistrationsStats("deregister", nfType, "SUCCESS")
return httpwrapper.NewResponse(http.StatusNoContent, nil, nil)
}
}
Expand Down Expand Up @@ -65,16 +69,19 @@ func HandleNFRegisterRequest(request *httpwrapper.Request) *httpwrapper.Response

if response != nil {
logger.ManagementLog.Traceln("register success")
stats.IncrementNrfRegistrationsStats("register", string(nfProfile.NfType), "SUCCESS")
return httpwrapper.NewResponse(http.StatusCreated, header, response)
} else if problemDetails != nil {
logger.ManagementLog.Traceln("register failed")
stats.IncrementNrfRegistrationsStats("register", string(nfProfile.NfType), "FAILURE")
return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails)
}
problemDetails = &models.ProblemDetails{
Status: http.StatusForbidden,
Cause: "UNSPECIFIED",
}
logger.ManagementLog.Traceln("register failed")
stats.IncrementNrfRegistrationsStats("register", string(nfProfile.NfType), "FAILURE")
return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails)
}

Expand All @@ -85,6 +92,7 @@ func HandleUpdateNFInstanceRequest(request *httpwrapper.Request) *httpwrapper.Re

response := UpdateNFInstanceProcedure(nfInstanceID, patchJSON)
if response != nil {
stats.IncrementNrfRegistrationsStats("update", fmt.Sprint(response["nfType"]), "SUCCESS")
return httpwrapper.NewResponse(http.StatusOK, nil, response)
} else {
return httpwrapper.NewResponse(http.StatusNoContent, nil, nil)
Expand Down Expand Up @@ -126,7 +134,9 @@ func HandleRemoveSubscriptionRequest(request *httpwrapper.Request) *httpwrapper.
logger.ManagementLog.Infoln("Handle RemoveSubscription")
subscriptionID := request.Params["subscriptionID"]

nfType := GetNfTypeBySubscriptionID(request.Params["subscriptionID"])
RemoveSubscriptionProcedure(subscriptionID)
stats.IncrementNrfSubscriptionsStats("unsubscribe", nfType, "SUCCESS")

return httpwrapper.NewResponse(http.StatusNoContent, nil, nil)
}
Expand All @@ -136,11 +146,14 @@ func HandleUpdateSubscriptionRequest(request *httpwrapper.Request) *httpwrapper.
subscriptionID := request.Params["subscriptionID"]
patchJSON := request.Body.([]byte)

nfType := GetNfTypeBySubscriptionID(subscriptionID)
response := UpdateSubscriptionProcedure(subscriptionID, patchJSON)

if response != nil {
stats.IncrementNrfSubscriptionsStats("update", nfType, "SUCCESS")
return httpwrapper.NewResponse(http.StatusOK, nil, response)
} else {
stats.IncrementNrfSubscriptionsStats("update", nfType, "FAILURE")
return httpwrapper.NewResponse(http.StatusNoContent, nil, nil)
}
}
Expand All @@ -152,16 +165,19 @@ func HandleCreateSubscriptionRequest(request *httpwrapper.Request) *httpwrapper.
response, problemDetails := CreateSubscriptionProcedure(subscription)
if response != nil {
logger.ManagementLog.Traceln("CreateSubscription success")
stats.IncrementNrfSubscriptionsStats("subscribe", string(subscription.ReqNfType), "SUCCESS")
return httpwrapper.NewResponse(http.StatusCreated, nil, response)
} else if problemDetails != nil {
logger.ManagementLog.Traceln("CreateSubscription failed")
stats.IncrementNrfSubscriptionsStats("subscribe", string(subscription.ReqNfType), "FAILURE")
return httpwrapper.NewResponse(int(problemDetails.Status), nil, problemDetails)
}
problemDetails = &models.ProblemDetails{
Status: http.StatusForbidden,
Cause: "UNSPECIFIED",
}
logger.ManagementLog.Traceln("CreateSubscription failed")
stats.IncrementNrfSubscriptionsStats("subscribe", string(subscription.ReqNfType), "FAILURE")
return httpwrapper.NewResponse(http.StatusForbidden, nil, problemDetails)
}

Expand Down Expand Up @@ -250,10 +266,10 @@ func NFDeleteAll(nfType string) (problemDetails *models.ProblemDetails) {
return nil
}

func NFDeregisterProcedure(nfInstanceID string) (problemDetails *models.ProblemDetails) {
func NFDeregisterProcedure(nfInstanceID string) (nfType string, problemDetails *models.ProblemDetails) {
collName := "NfProfile"
filter := bson.M{"nfInstanceId": nfInstanceID}

nfType = GetNfTypeByNfInstanceID(nfInstanceID)
nfProfilesRaw, _ := dbadapter.DBClient.RestfulAPIGetMany(collName, filter)
time.Sleep(time.Duration(1) * time.Second)

Expand All @@ -268,31 +284,33 @@ func NFDeregisterProcedure(nfInstanceID string) (problemDetails *models.ProblemD
Cause: "NOTIFICATION_ERROR",
Detail: err.Error(),
}
return problemDetails
return "", problemDetails
}

/* NF Down Notification to other instances of same NfType */
sendNFDownNotification(nfProfiles[0], nfInstanceID)
if len(nfProfiles) != 0 {
sendNFDownNotification(nfProfiles[0], nfInstanceID)

uriList := nrf_context.GetNofificationUri(nfProfiles[0])
uriList := nrf_context.GetNofificationUri(nfProfiles[0])

nfInstanceUri := nrf_context.GetNfInstanceURI(nfInstanceID)
// set info for NotificationData
Notification_event := models.NotificationEventType_DEREGISTERED
nfInstanceUri := nrf_context.GetNfInstanceURI(nfInstanceID)
// set info for NotificationData
Notification_event := models.NotificationEventType_DEREGISTERED

for _, uri := range uriList {
logger.ManagementLog.Infof("Status Notification Uri: %v", uri)
problemDetails = SendNFStatusNotify(Notification_event, nfInstanceUri, uri)
if problemDetails != nil {
logger.ManagementLog.Infoln("Error in status notify ", problemDetails)
for _, uri := range uriList {
logger.ManagementLog.Infof("Status Notification Uri: %v", uri)
problemDetails = SendNFStatusNotify(Notification_event, nfInstanceUri, uri)
if problemDetails != nil {
logger.ManagementLog.Infoln("Error in status notify ", problemDetails)
}
}
}

/* delete subscriptions of deregistered NF instance */
filter = bson.M{"subscrCond.nfInstanceId": nfInstanceID}
dbadapter.DBClient.RestfulAPIDeleteMany("Subscriptions", filter)

return nil
return nfType, nil
}

func sendNFDownNotification(nfProfile models.NfProfile, nfInstanceID string) {
Expand Down Expand Up @@ -456,6 +474,32 @@ func NFRegisterProcedure(nfProfile models.NfProfile) (header http.Header, respon
}
}

func GetNfTypeBySubscriptionID(subscriptionID string) (nfType string) {
collName := "Subscriptions"
filter := bson.M{"subscriptionId": subscriptionID}
response, err := dbadapter.DBClient.RestfulAPIGetOne(collName, filter)
if err != nil {
return "UNKNOWN_NF"
}
if response["reqNfType"] != nil {
return fmt.Sprint(response["reqNfType"])
}
return "UNKNOWN_NF"
}

func GetNfTypeByNfInstanceID(nfInstanceID string) (nfType string) {
collName := "NfProfile"
filter := bson.M{"nfInstanceId": nfInstanceID}
response, err := dbadapter.DBClient.RestfulAPIGetOne(collName, filter)
if err != nil {
return "UNKNOWN_NF"
}
if response["nfType"] != nil {
return fmt.Sprint(response["nfType"])
}
return "UNKNOWN_NF"
}

func SendNFStatusNotify(Notification_event models.NotificationEventType, nfInstanceUri string,
url string) *models.ProblemDetails {
// Set client and set url
Expand Down

0 comments on commit 3df6b3c

Please sign in to comment.