Add route update metrics tracking to PrefixHandler

- Add RecordIPv4Update and RecordIPv6Update to metrics package
- Add SetMetricsTracker method to PrefixHandler
- Track IPv4/IPv6 route updates when processing announcements
- Add GetMetricsTracker method to Streamer to expose metrics
This commit is contained in:
Jeffrey Paul 2025-07-28 02:55:27 +02:00
parent bc640b0b37
commit cb1f4d9052
4 changed files with 54 additions and 2 deletions

View File

@ -21,6 +21,10 @@ type Tracker struct {
byteCounter metrics.Counter
messageRate metrics.Meter
byteRate metrics.Meter
// Route update metrics
ipv4UpdateRate metrics.Meter
ipv6UpdateRate metrics.Meter
}
// New creates a new metrics tracker
@ -33,6 +37,8 @@ func New() *Tracker {
byteCounter: metrics.NewCounter(),
messageRate: metrics.NewMeter(),
byteRate: metrics.NewMeter(),
ipv4UpdateRate: metrics.NewMeter(),
ipv6UpdateRate: metrics.NewMeter(),
}
}
@ -89,6 +95,24 @@ func (t *Tracker) GetStreamMetrics() StreamMetrics {
}
}
// RecordIPv4Update records an IPv4 route update
func (t *Tracker) RecordIPv4Update() {
t.ipv4UpdateRate.Mark(1)
}
// RecordIPv6Update records an IPv6 route update
func (t *Tracker) RecordIPv6Update() {
t.ipv6UpdateRate.Mark(1)
}
// GetRouteMetrics returns current route update metrics
func (t *Tracker) GetRouteMetrics() RouteMetrics {
return RouteMetrics{
IPv4UpdatesPerSec: t.ipv4UpdateRate.Rate1(),
IPv6UpdatesPerSec: t.ipv6UpdateRate.Rate1(),
}
}
// StreamMetrics contains streaming statistics
type StreamMetrics struct {
TotalMessages uint64
@ -98,3 +122,9 @@ type StreamMetrics struct {
MessagesPerSec float64
BitsPerSec float64
}
// RouteMetrics contains route update statistics
type RouteMetrics struct {
IPv4UpdatesPerSec float64
IPv6UpdatesPerSec float64
}

View File

@ -118,6 +118,7 @@ func (rw *RouteWatch) Run(ctx context.Context) error {
// PrefixHandler maintains the prefixes and live_routes tables
rw.prefixHandler = NewPrefixHandler(rw.db, rw.logger)
rw.prefixHandler.SetMetricsTracker(rw.streamer.GetMetricsTracker())
rw.streamer.RegisterHandler(rw.prefixHandler)
// PeeringHandler maintains the asn_peerings table

View File

@ -8,6 +8,7 @@ import (
"git.eeqj.de/sneak/routewatch/internal/database"
"git.eeqj.de/sneak/routewatch/internal/logger"
"git.eeqj.de/sneak/routewatch/internal/metrics"
"git.eeqj.de/sneak/routewatch/internal/ristypes"
"github.com/google/uuid"
)
@ -30,8 +31,9 @@ const (
// PrefixHandler tracks BGP prefixes and maintains a live routing table in the database.
// Routes are added on announcement and deleted on withdrawal.
type PrefixHandler struct {
db database.Store
logger *logger.Logger
db database.Store
logger *logger.Logger
metrics *metrics.Tracker
// Batching
mu sync.Mutex
@ -67,6 +69,11 @@ func NewPrefixHandler(db database.Store, logger *logger.Logger) *PrefixHandler {
return h
}
// SetMetricsTracker sets the metrics tracker for recording route updates
func (h *PrefixHandler) SetMetricsTracker(metrics *metrics.Tracker) {
h.metrics = metrics
}
// WantsMessage returns true if this handler wants to process messages of the given type
func (h *PrefixHandler) WantsMessage(messageType string) bool {
// We only care about UPDATE messages for the routing table
@ -220,6 +227,15 @@ func (h *PrefixHandler) processAnnouncement(_ *database.Prefix, update prefixUpd
return
}
// Track route update metrics
if h.metrics != nil {
if ipVersion == ipv4Version {
h.metrics.RecordIPv4Update()
} else {
h.metrics.RecordIPv6Update()
}
}
// Create live route record
liveRoute := &database.LiveRoute{
ID: uuid.New(),

View File

@ -195,6 +195,11 @@ func (s *Streamer) GetMetrics() metrics.StreamMetrics {
return s.metrics.GetStreamMetrics()
}
// GetMetricsTracker returns the metrics tracker instance
func (s *Streamer) GetMetricsTracker() *metrics.Tracker {
return s.metrics
}
// HandlerStats represents metrics for a single handler
type HandlerStats struct {
Name string