diff --git a/cmd/api/rest/handler.go b/cmd/api/rest/handler.go index 1f78dd96..33fa34f9 100644 --- a/cmd/api/rest/handler.go +++ b/cmd/api/rest/handler.go @@ -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) } }()) diff --git a/cmd/api/rest/stats.go b/cmd/api/rest/stats.go index 6533b7dd..8f1b9729 100644 --- a/cmd/api/rest/stats.go +++ b/cmd/api/rest/stats.go @@ -30,6 +30,7 @@ type PacketStats struct { } // DisplayXdpStatistics godoc +// // @Summary Display XDP statistics // @Description Display XDP statistics // @Tags XDP @@ -47,6 +48,7 @@ func (h *ApiHandler) displayXdpStatistics(c *gin.Context) { } // DisplayPacketStats godoc +// // @Summary Display packet statistics // @Description Display packet statistics // @Tags Packet @@ -54,7 +56,7 @@ func (h *ApiHandler) displayXdpStatistics(c *gin.Context) { // @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, diff --git a/cmd/core/metrics.go b/cmd/core/metrics.go index fa4f711f..25d8cec3 100644 --- a/cmd/core/metrics.go +++ b/cmd/core/metrics.go @@ -2,7 +2,6 @@ package core import ( "net/http" - "time" "github.com/edgecomllc/eupf/cmd/ebpf" @@ -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 - }() } diff --git a/cmd/ebpf/stats.go b/cmd/ebpf/stats.go index f963811d..b65f1e3e 100644 --- a/cmd/ebpf/stats.go +++ b/cmd/ebpf/stats.go @@ -6,6 +6,7 @@ import ( type UpfXdpActionStatistic struct { BpfObjects *BpfObjects + previous UpfCounters } type UpfCounters struct { @@ -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 { @@ -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 @@ -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 +}