Compare commits

..

No commits in common. "81267431f7a2cd696a5a80ba7e834a79c7c0fc8d" and "a78e5c6e922100af9d8812e2f6b6984077803208" have entirely different histories.

6 changed files with 270951 additions and 64 deletions

View File

@ -11,14 +11,12 @@ import (
const ( const (
// asHandlerQueueSize is the queue capacity for ASN operations // asHandlerQueueSize is the queue capacity for ASN operations
// DO NOT set this higher than 100000 without explicit instructions
asHandlerQueueSize = 100000 asHandlerQueueSize = 100000
// asnBatchSize is the number of ASN operations to batch together // asnBatchSize is the number of ASN operations to batch together
asnBatchSize = 30000 asnBatchSize = 10000
// asnBatchTimeout is the maximum time to wait before flushing a batch // asnBatchTimeout is the maximum time to wait before flushing a batch
// DO NOT reduce this timeout - larger batches are more efficient
asnBatchTimeout = 2 * time.Second asnBatchTimeout = 2 * time.Second
) )

View File

@ -15,14 +15,12 @@ import (
const ( const (
// prefixHandlerQueueSize is the queue capacity for prefix tracking operations // prefixHandlerQueueSize is the queue capacity for prefix tracking operations
// DO NOT set this higher than 100000 without explicit instructions
prefixHandlerQueueSize = 100000 prefixHandlerQueueSize = 100000
// prefixBatchSize is the number of prefix updates to batch together // prefixBatchSize is the number of prefix updates to batch together
prefixBatchSize = 20000 prefixBatchSize = 5000
// prefixBatchTimeout is the maximum time to wait before flushing a batch // prefixBatchTimeout is the maximum time to wait before flushing a batch
// DO NOT reduce this timeout - larger batches are more efficient
prefixBatchTimeout = 1 * time.Second prefixBatchTimeout = 1 * time.Second
// IP version constants // IP version constants

View File

@ -15,16 +15,10 @@ import (
"git.eeqj.de/sneak/routewatch/internal/database" "git.eeqj.de/sneak/routewatch/internal/database"
"git.eeqj.de/sneak/routewatch/internal/templates" "git.eeqj.de/sneak/routewatch/internal/templates"
"git.eeqj.de/sneak/routewatch/pkg/asinfo"
"github.com/dustin/go-humanize" "github.com/dustin/go-humanize"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
) )
const (
// maxASDescriptionLength is the maximum length for AS descriptions in the UI
maxASDescriptionLength = 20
)
// handleRoot returns a handler that redirects to /status // handleRoot returns a handler that redirects to /status
func (s *Server) handleRoot() http.HandlerFunc { func (s *Server) handleRoot() http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
@ -651,45 +645,12 @@ func (s *Server) handlePrefixDetail() http.HandlerFunc {
origins = append(origins, origin) origins = append(origins, origin)
} }
// Create enhanced routes with AS path descriptions
type ASPathEntry struct {
Number int
Description string
}
type EnhancedRoute struct {
database.LiveRoute
ASPathWithDesc []ASPathEntry
}
enhancedRoutes := make([]EnhancedRoute, len(routes))
for i, route := range routes {
enhancedRoute := EnhancedRoute{
LiveRoute: route,
ASPathWithDesc: make([]ASPathEntry, len(route.ASPath)),
}
// Look up description for each AS in the path
for j, asn := range route.ASPath {
desc := asinfo.GetDescription(asn)
// Truncate description if longer than maxASDescriptionLength characters
if len(desc) > maxASDescriptionLength {
desc = desc[:maxASDescriptionLength] + "..."
}
enhancedRoute.ASPathWithDesc[j] = ASPathEntry{
Number: asn,
Description: desc,
}
}
enhancedRoutes[i] = enhancedRoute
}
// Prepare template data // Prepare template data
data := struct { data := struct {
Prefix string Prefix string
MaskLength int MaskLength int
IPVersion int IPVersion int
Routes []EnhancedRoute Routes []database.LiveRoute
Origins []*ASNInfo Origins []*ASNInfo
PeerCount int PeerCount int
OriginCount int OriginCount int
@ -697,7 +658,7 @@ func (s *Server) handlePrefixDetail() http.HandlerFunc {
Prefix: prefix, Prefix: prefix,
MaskLength: maskLength, MaskLength: maskLength,
IPVersion: ipVersion, IPVersion: ipVersion,
Routes: enhancedRoutes, Routes: routes,
Origins: origins, Origins: origins,
PeerCount: len(routes), PeerCount: len(routes),
OriginCount: len(originMap), OriginCount: len(originMap),

View File

@ -7,7 +7,6 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math"
"net/http" "net/http"
"os" "os"
"sync" "sync"
@ -96,9 +95,6 @@ func (s *Streamer) RegisterHandler(handler MessageHandler) {
info := &handlerInfo{ info := &handlerInfo{
handler: handler, handler: handler,
queue: make(chan *ristypes.RISMessage, handler.QueueCapacity()), queue: make(chan *ristypes.RISMessage, handler.QueueCapacity()),
metrics: handlerMetrics{
minTime: time.Duration(math.MaxInt64), // Initialize to max so first value sets the floor
},
} }
s.handlers = append(s.handlers, info) s.handlers = append(s.handlers, info)
@ -174,7 +170,7 @@ func (s *Streamer) runHandlerWorker(info *handlerInfo) {
info.metrics.totalTime += elapsed info.metrics.totalTime += elapsed
// Update min time // Update min time
if elapsed < info.metrics.minTime { if info.metrics.minTime == 0 || elapsed < info.metrics.minTime {
info.metrics.minTime = elapsed info.metrics.minTime = elapsed
} }

View File

@ -13,8 +13,7 @@
color: #333; color: #333;
} }
.container { .container {
width: 90%; max-width: 1200px;
max-width: 1600px;
margin: 0 auto; margin: 0 auto;
background: white; background: white;
padding: 30px; padding: 30px;
@ -115,10 +114,9 @@
font-family: monospace; font-family: monospace;
font-size: 13px; font-size: 13px;
color: #666; color: #666;
max-width: 600px; max-width: 300px;
word-wrap: break-word; overflow-x: auto;
white-space: normal; white-space: nowrap;
line-height: 1.5;
} }
.age { .age {
color: #7f8c8d; color: #7f8c8d;
@ -170,7 +168,7 @@
font-size: 14px; font-size: 14px;
} }
.as-path { .as-path {
max-width: 100%; max-width: 150px;
} }
} }
</style> </style>
@ -236,7 +234,7 @@
<a href="/as/{{.OriginASN}}" class="as-link">AS{{.OriginASN}}</a> <a href="/as/{{.OriginASN}}" class="as-link">AS{{.OriginASN}}</a>
</td> </td>
<td class="peer-ip">{{.PeerIP}}</td> <td class="peer-ip">{{.PeerIP}}</td>
<td class="as-path">{{range $i, $as := .ASPathWithDesc}}{{if $i}} → {{end}}{{if $as.Description}}{{$as.Description}} ({{$as.Number}}){{else}}AS{{$as.Number}}{{end}}{{end}}</td> <td class="as-path">{{range $i, $as := .ASPath}}{{if $i}} → {{end}}{{$as}}{{end}}</td>
<td class="peer-ip">{{.NextHop}}</td> <td class="peer-ip">{{.NextHop}}</td>
<td>{{.LastUpdated.Format "2006-01-02 15:04:05"}}</td> <td>{{.LastUpdated.Format "2006-01-02 15:04:05"}}</td>
<td class="age">{{.LastUpdated | timeSince}}</td> <td class="age">{{.LastUpdated | timeSince}}</td>

270944
log.txt

File diff suppressed because it is too large Load Diff