server: expose Handle/HandleFunc for custom checker routes

Lets plugins register auxiliary endpoints (debug pages, webhooks, UI
assets) on the SDK mux, with TrackWork as an opt-in for the /health
load signal.
This commit is contained in:
nemunaire 2026-04-23 10:12:55 +07:00
commit 0c6a886e82
2 changed files with 50 additions and 11 deletions

View file

@ -111,19 +111,21 @@ func NewServer(provider ObservationProvider) *Server {
}
s.mux = http.NewServeMux()
s.mux.HandleFunc("GET /health", s.handleHealth)
s.mux.Handle("POST /collect", s.trackWork(http.HandlerFunc(s.handleCollect)))
s.mux.Handle("POST /collect", s.TrackWork(http.HandlerFunc(s.handleCollect)))
if dp, ok := provider.(CheckerDefinitionProvider); ok {
s.definition = dp.Definition()
s.definition.BuildRulesInfo()
s.mux.HandleFunc("GET /definition", s.handleDefinition)
s.mux.Handle("POST /evaluate", s.trackWork(http.HandlerFunc(s.handleEvaluate)))
if def := dp.Definition(); def != nil {
s.definition = def
s.definition.BuildRulesInfo()
s.mux.HandleFunc("GET /definition", s.handleDefinition)
s.mux.Handle("POST /evaluate", s.TrackWork(http.HandlerFunc(s.handleEvaluate)))
}
}
if _, ok := provider.(CheckerHTMLReporter); ok {
s.mux.Handle("POST /report", s.trackWork(http.HandlerFunc(s.handleReport)))
s.mux.Handle("POST /report", s.TrackWork(http.HandlerFunc(s.handleReport)))
} else if _, ok := provider.(CheckerMetricsReporter); ok {
s.mux.Handle("POST /report", s.trackWork(http.HandlerFunc(s.handleReport)))
s.mux.Handle("POST /report", s.TrackWork(http.HandlerFunc(s.handleReport)))
}
go s.runSampler(ctx)
@ -137,6 +139,18 @@ func (s *Server) Handler() http.Handler {
return requestLogger(s.mux)
}
// Handle registers an auxiliary handler on the server's mux. Must be called
// before ListenAndServe or Handler(). Custom handlers are not tracked by
// TrackWork; wrap them explicitly if you want them counted in /health load.
func (s *Server) Handle(pattern string, handler http.Handler) {
s.mux.Handle(pattern, handler)
}
// HandleFunc is the http.HandlerFunc-flavoured counterpart of Handle.
func (s *Server) HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)) {
s.mux.HandleFunc(pattern, handler)
}
// ListenAndServe starts the HTTP server on the given address.
//
// ListenAndServe does not stop the background load-average sampler on return;
@ -158,10 +172,9 @@ func (s *Server) Close() error {
return nil
}
// trackWork wraps a handler with in-flight and total-request accounting.
// It is applied only to "work" endpoints (/collect, /evaluate, /report) so
// that /health polling traffic does not pollute the load signal.
func (s *Server) trackWork(next http.Handler) http.Handler {
// TrackWork wraps a handler with in-flight and total-request accounting,
// opting custom routes into the load signal reported on /health.
func (s *Server) TrackWork(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
s.inFlight.Add(1)
s.totalRequests.Add(1)