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:
2025-07-27 21:18:57 +02:00
commit 92f7527cc5
24 changed files with 3587 additions and 0 deletions

55
cmd/streamdumper/main.go Normal file
View File

@@ -0,0 +1,55 @@
// Package main provides a utility to dump raw RIS Live stream messages to stdout
package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
"syscall"
"git.eeqj.de/sneak/routewatch/internal/metrics"
"git.eeqj.de/sneak/routewatch/internal/streamer"
"log/slog"
)
func main() {
// Set up logger to only show errors
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{
Level: slog.LevelError,
}))
// Create metrics tracker
metricsTracker := metrics.New()
// Create streamer
s := streamer.New(logger, metricsTracker)
// Register raw message handler that prints to stdout
s.RegisterRawHandler(func(line string) {
fmt.Println(line)
})
// Set up context with cancellation
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// Handle signals
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
go func() {
<-sigChan
log.Println("Received shutdown signal")
cancel()
}()
// Start streaming
if err := s.Start(); err != nil {
log.Fatal("Failed to start streamer:", err)
}
defer s.Stop()
// Wait for context cancellation
<-ctx.Done()
}