Initial commit: RouteWatch BGP stream monitor
- Connects to RIPE RIS Live stream to receive real-time BGP updates - Stores BGP data in SQLite database: - ASNs with first/last seen timestamps - Prefixes with IPv4/IPv6 classification - BGP announcements and withdrawals - AS-to-AS peering relationships from AS paths - Live routing table tracking active routes - HTTP server with statistics endpoints - Metrics tracking with go-metrics - Custom JSON unmarshaling to handle nested AS sets in paths - Dependency injection with uber/fx - Pure Go implementation (no CGO) - Includes streamdumper utility for debugging raw messages
This commit is contained in:
100
internal/metrics/metrics.go
Normal file
100
internal/metrics/metrics.go
Normal file
@@ -0,0 +1,100 @@
|
||||
// Package metrics provides centralized metrics tracking for the RouteWatch application
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/rcrowley/go-metrics"
|
||||
)
|
||||
|
||||
// Tracker provides centralized metrics tracking
|
||||
type Tracker struct {
|
||||
mu sync.RWMutex
|
||||
registry metrics.Registry
|
||||
connectedSince time.Time
|
||||
isConnected atomic.Bool
|
||||
|
||||
// Stream metrics
|
||||
messageCounter metrics.Counter
|
||||
byteCounter metrics.Counter
|
||||
messageRate metrics.Meter
|
||||
byteRate metrics.Meter
|
||||
}
|
||||
|
||||
// New creates a new metrics tracker
|
||||
func New() *Tracker {
|
||||
registry := metrics.NewRegistry()
|
||||
|
||||
return &Tracker{
|
||||
registry: registry,
|
||||
messageCounter: metrics.NewCounter(),
|
||||
byteCounter: metrics.NewCounter(),
|
||||
messageRate: metrics.NewMeter(),
|
||||
byteRate: metrics.NewMeter(),
|
||||
}
|
||||
}
|
||||
|
||||
// SetConnected updates the connection status
|
||||
func (t *Tracker) SetConnected(connected bool) {
|
||||
t.isConnected.Store(connected)
|
||||
if connected {
|
||||
t.mu.Lock()
|
||||
t.connectedSince = time.Now()
|
||||
t.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// IsConnected returns the current connection status
|
||||
func (t *Tracker) IsConnected() bool {
|
||||
return t.isConnected.Load()
|
||||
}
|
||||
|
||||
// RecordMessage records a received message and its size
|
||||
func (t *Tracker) RecordMessage(bytes int64) {
|
||||
t.messageCounter.Inc(1)
|
||||
t.byteCounter.Inc(bytes)
|
||||
t.messageRate.Mark(1)
|
||||
t.byteRate.Mark(bytes)
|
||||
}
|
||||
|
||||
// GetStreamMetrics returns current streaming metrics
|
||||
func (t *Tracker) GetStreamMetrics() StreamMetrics {
|
||||
t.mu.RLock()
|
||||
connectedSince := t.connectedSince
|
||||
t.mu.RUnlock()
|
||||
|
||||
const bitsPerByte = 8
|
||||
|
||||
// Safely convert counters to uint64
|
||||
msgCount := t.messageCounter.Count()
|
||||
byteCount := t.byteCounter.Count()
|
||||
|
||||
var totalMessages, totalBytes uint64
|
||||
if msgCount >= 0 {
|
||||
totalMessages = uint64(msgCount)
|
||||
}
|
||||
if byteCount >= 0 {
|
||||
totalBytes = uint64(byteCount)
|
||||
}
|
||||
|
||||
return StreamMetrics{
|
||||
TotalMessages: totalMessages,
|
||||
TotalBytes: totalBytes,
|
||||
ConnectedSince: connectedSince,
|
||||
Connected: t.isConnected.Load(),
|
||||
MessagesPerSec: t.messageRate.Rate1(),
|
||||
BitsPerSec: t.byteRate.Rate1() * bitsPerByte,
|
||||
}
|
||||
}
|
||||
|
||||
// StreamMetrics contains streaming statistics
|
||||
type StreamMetrics struct {
|
||||
TotalMessages uint64
|
||||
TotalBytes uint64
|
||||
ConnectedSince time.Time
|
||||
Connected bool
|
||||
MessagesPerSec float64
|
||||
BitsPerSec float64
|
||||
}
|
||||
Reference in New Issue
Block a user