Skip to content

Commit

Permalink
fix: packet metrics gathering (#584)
Browse files Browse the repository at this point in the history
Co-authored-by: pirog-spb <[email protected]>
  • Loading branch information
pirog-spb and pirog-spb authored Dec 18, 2024
1 parent a1d1f14 commit 72cd736
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 24 deletions.
1 change: 1 addition & 0 deletions cmd/api/rest/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ func (h *ApiHandler) InitMetricsRoute() *gin.Engine {

router.GET("/metrics", func() gin.HandlerFunc {
return func(c *gin.Context) {
core.GatherMetrics(*h.ForwardPlaneStats)
promhttp.Handler().ServeHTTP(c.Writer, c.Request)
}
}())
Expand Down
4 changes: 3 additions & 1 deletion cmd/api/rest/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type PacketStats struct {
}

// DisplayXdpStatistics godoc
//
// @Summary Display XDP statistics
// @Description Display XDP statistics
// @Tags XDP
Expand All @@ -47,14 +48,15 @@ func (h *ApiHandler) displayXdpStatistics(c *gin.Context) {
}

// DisplayPacketStats godoc
//
// @Summary Display packet statistics
// @Description Display packet statistics
// @Tags Packet
// @Produce json
// @Success 200 {object} PacketStats
// @Router /packet_stats [get]
func (h *ApiHandler) displayPacketStats(c *gin.Context) {
packets := h.ForwardPlaneStats.GetUpfExtStatField()
packets := h.ForwardPlaneStats.GetUpfExtStat()
c.IndentedJSON(http.StatusOK, PacketStats{
RxArp: packets.RxArp,
RxIcmp: packets.RxIcmp,
Expand Down
37 changes: 16 additions & 21 deletions cmd/core/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package core

import (
"net/http"
"time"

"github.com/edgecomllc/eupf/cmd/ebpf"

Expand Down Expand Up @@ -113,25 +112,21 @@ func RegisterMetrics(stats ebpf.UpfXdpActionStatistic, conn *PfcpConnection) {
prometheus.MustRegister(UpfXdpRedirect)
prometheus.MustRegister(UpfPfcpSessions)
prometheus.MustRegister(UpfPfcpAssociations)
}

func GatherMetrics(stats ebpf.UpfXdpActionStatistic) {
RxPacketCounters := stats.GetUpfExtStatDelta()
UpfRx.WithLabelValues("arp").Add(float64(RxPacketCounters.RxArp))
UpfRx.WithLabelValues("icmp").Add(float64(RxPacketCounters.RxIcmp))
UpfRx.WithLabelValues("icmp6").Add(float64(RxPacketCounters.RxIcmp6))
UpfRx.WithLabelValues("ip4").Add(float64(RxPacketCounters.RxIp4))
UpfRx.WithLabelValues("ip6").Add(float64(RxPacketCounters.RxIp6))
UpfRx.WithLabelValues("tcp").Add(float64(RxPacketCounters.RxTcp))
UpfRx.WithLabelValues("udp").Add(float64(RxPacketCounters.RxUdp))
UpfRx.WithLabelValues("other").Add(float64(RxPacketCounters.RxOther))
UpfRx.WithLabelValues("gtp-echo").Add(float64(RxPacketCounters.RxGtpEcho))
UpfRx.WithLabelValues("gtp-pdu").Add(float64(RxPacketCounters.RxGtpPdu))
UpfRx.WithLabelValues("gtp-other").Add(float64(RxPacketCounters.RxGtpOther))
UpfRx.WithLabelValues("gtp-unexp").Add(float64(RxPacketCounters.RxGtpUnexp))

// Used for getting difference between two counters to increment the prometheus counter (counters cannot be written only incremented)
var prevUpfCounters ebpf.UpfCounters
go func() {
time.Sleep(2 * time.Second)
RxPacketCounters := stats.GetUpfExtStatField()
UpfRx.WithLabelValues("Arp").Add(float64(RxPacketCounters.RxArp - prevUpfCounters.RxArp))
UpfRx.WithLabelValues("Icmp").Add(float64(RxPacketCounters.RxIcmp - prevUpfCounters.RxIcmp))
UpfRx.WithLabelValues("Icmp6").Add(float64(RxPacketCounters.RxIcmp6 - prevUpfCounters.RxIcmp6))
UpfRx.WithLabelValues("Ip4").Add(float64(RxPacketCounters.RxIp4 - prevUpfCounters.RxIp4))
UpfRx.WithLabelValues("Ip6").Add(float64(RxPacketCounters.RxIp6 - prevUpfCounters.RxIp6))
UpfRx.WithLabelValues("Tcp").Add(float64(RxPacketCounters.RxTcp - prevUpfCounters.RxTcp))
UpfRx.WithLabelValues("Udp").Add(float64(RxPacketCounters.RxUdp - prevUpfCounters.RxUdp))
UpfRx.WithLabelValues("Other").Add(float64(RxPacketCounters.RxOther - prevUpfCounters.RxOther))
UpfRx.WithLabelValues("GtpEcho").Add(float64(RxPacketCounters.RxGtpEcho - prevUpfCounters.RxGtpEcho))
UpfRx.WithLabelValues("GtpPdu").Add(float64(RxPacketCounters.RxGtpPdu - prevUpfCounters.RxGtpPdu))
UpfRx.WithLabelValues("GtpOther").Add(float64(RxPacketCounters.RxGtpOther - prevUpfCounters.RxGtpOther))
UpfRx.WithLabelValues("GtpUnexp").Add(float64(RxPacketCounters.RxGtpUnexp - prevUpfCounters.RxGtpUnexp))

prevUpfCounters = RxPacketCounters
}()
}
42 changes: 40 additions & 2 deletions cmd/ebpf/stats.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

type UpfXdpActionStatistic struct {
BpfObjects *BpfObjects
previous UpfCounters
}

type UpfCounters struct {
Expand Down Expand Up @@ -42,6 +43,24 @@ func (current *UpfCounters) Add(new UpfCounters) {
current.RxGtpOther += new.RxGtpOther
}

func (current *UpfCounters) Delta(new UpfCounters) UpfCounters {

delta := UpfCounters{}

delta.RxArp = new.RxArp - current.RxArp
delta.RxIcmp = new.RxIcmp - current.RxIcmp
delta.RxIcmp6 = new.RxIcmp6 - current.RxIcmp6
delta.RxIp4 = new.RxIp4 - current.RxIp4
delta.RxIp6 = new.RxIp6 - current.RxIp6
delta.RxTcp = new.RxTcp - current.RxTcp
delta.RxUdp = new.RxUdp - current.RxUdp
delta.RxOther = new.RxOther - current.RxOther
delta.RxGtpEcho = new.RxGtpEcho - current.RxGtpEcho
delta.RxGtpPdu = new.RxGtpPdu - current.RxGtpPdu
delta.RxGtpOther = new.RxGtpOther - current.RxGtpOther
return delta
}

// Getters for the upf_xdp_statistic (xdp_action)

func (stat *UpfXdpActionStatistic) getUpfXdpStatisticField(field uint32) uint64 {
Expand Down Expand Up @@ -82,8 +101,7 @@ func (stat *UpfXdpActionStatistic) GetRedirect() uint64 {
}

// Getters for the upf_ext_stat (upf_counters)
// #TODO: Do not retrieve the whole struct each time.
func (stat *UpfXdpActionStatistic) GetUpfExtStatField() UpfCounters {
func (stat *UpfXdpActionStatistic) GetUpfExtStat() UpfCounters {

var statistics []IpEntrypointUpfStatistic
var counters UpfCounters
Expand All @@ -99,3 +117,23 @@ func (stat *UpfXdpActionStatistic) GetUpfExtStatField() UpfCounters {

return counters
}

// Getters for the upf_ext_stat (upf_counters)
func (stat *UpfXdpActionStatistic) GetUpfExtStatDelta() UpfCounters {

var statistics []IpEntrypointUpfStatistic
var counters UpfCounters
err := stat.BpfObjects.UpfExtStat.Lookup(uint32(0), &statistics)
if err != nil {
log.Info().Msg(err.Error())
return counters
}

for _, statistic := range statistics {
counters.Add(statistic.UpfCounters)
}

delta := stat.previous.Delta(counters)
stat.previous = counters
return delta
}

0 comments on commit 72cd736

Please sign in to comment.