Skip to content

Commit 94e7761

Browse files
committed
www: add the ability to only check for bad resolvers
1 parent ab229c8 commit 94e7761

1 file changed

Lines changed: 45 additions & 0 deletions

File tree

www/main.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package main
22

33
import (
44
"flag"
5+
"fmt"
56
"log"
67
"os"
78
"os/signal"
9+
"sort"
810
"syscall"
911
"time"
1012
)
@@ -22,6 +24,7 @@ func main() {
2224
clearErrors := flag.String("clear-errors", "", "Clear all errors for a resolver (mark as successful) and exit")
2325
hideLatency := flag.Bool("hide-latency", false, "Hide latency column in web interface")
2426
minReliability := flag.Float64("min-reliability", -1, "Remove resolvers with reliability below this percentage and exit")
27+
showFailures := flag.Bool("failures", false, "Print failing resolvers/relays with their error messages and exit")
2528
flag.Parse()
2629

2730
log.SetFlags(log.LstdFlags | log.Lshortfile)
@@ -78,6 +81,23 @@ func main() {
7881
return
7982
}
8083

84+
// Handle showing failures
85+
if *showFailures {
86+
stats, err := db.GetAllStats()
87+
if err != nil {
88+
log.Fatalf("Failed to get stats: %v", err)
89+
}
90+
failures := filterFailures(stats)
91+
if len(failures) == 0 {
92+
log.Println("No failing resolvers/relays")
93+
return
94+
}
95+
for _, s := range failures {
96+
fmt.Printf("%s (%s): %s\n", s.Name, s.Type, s.LastError)
97+
}
98+
return
99+
}
100+
81101
// Auto-rebuild if resolver_stats is empty but test_results has data
82102
if err := db.RebuildStatsIfNeeded(); err != nil {
83103
log.Printf("Warning: failed to check/rebuild stats: %v", err)
@@ -150,3 +170,28 @@ func main() {
150170
}
151171
}
152172
}
173+
174+
// filterFailures returns resolvers where the last test failed.
175+
// A resolver is considered failing if it has a LastFail time that is
176+
// more recent than LastSuccess (or if it has never succeeded).
177+
func filterFailures(stats []ResolverStats) []ResolverStats {
178+
var failures []ResolverStats
179+
for _, s := range stats {
180+
if s.LastError == "" {
181+
continue
182+
}
183+
// Consider it failing if last_fail > last_success
184+
if s.LastFail != nil {
185+
if s.LastSuccess == nil || s.LastFail.After(*s.LastSuccess) {
186+
failures = append(failures, s)
187+
}
188+
}
189+
}
190+
sort.Slice(failures, func(i, j int) bool {
191+
if failures[i].Type != failures[j].Type {
192+
return failures[i].Type < failures[j].Type
193+
}
194+
return failures[i].Name < failures[j].Name
195+
})
196+
return failures
197+
}

0 commit comments

Comments
 (0)