Skip to content

Commit

Permalink
add metrics and logs for HTTP requests (#80)
Browse files Browse the repository at this point in the history
Signed-off-by: Dmitry Shmulevich <[email protected]>
  • Loading branch information
dmitsh authored Feb 27, 2025
1 parent 88a33d2 commit f844abf
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 14 deletions.
27 changes: 16 additions & 11 deletions pkg/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,20 @@ import (
)

var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "requests_total",
Help: "Total number of topology generation requests.",
httpRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "http_request_duration_seconds",
Help: "HTTP request duration in seconds.",
Subsystem: "topograph",
Buckets: prometheus.DefBuckets,
},
[]string{"provider", "engine", "status"},
[]string{"method", "path", "proto", "from", "status"},
)

httpRequestDuration = prometheus.NewHistogramVec(
topologyRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "request_duration_seconds",
Help: "Topology generator request duration in seconds.",
Help: "Topology request duration in seconds.",
Subsystem: "topograph",
Buckets: prometheus.DefBuckets,
},
Expand All @@ -63,16 +64,20 @@ var (
)

func init() {
prometheus.MustRegister(httpRequestsTotal)
prometheus.MustRegister(httpRequestDuration)
prometheus.MustRegister(topologyRequestDuration)
prometheus.MustRegister(missingTopologyNodes)
prometheus.MustRegister(validationErrorsTotal)
}

func Add(provider, engine string, code int, duration time.Duration) {
func AddHttpRequest(method, path, proto, from string, code int, duration time.Duration) {
status := fmt.Sprintf("%d", code)
httpRequestDuration.WithLabelValues(method, path, proto, from, status).Observe(duration.Seconds())
}

func AddTopologyRequest(provider, engine string, code int, duration time.Duration) {
status := fmt.Sprintf("%d", code)
httpRequestsTotal.WithLabelValues(provider, engine, status).Inc()
httpRequestDuration.WithLabelValues(provider, engine, status).Observe(duration.Seconds())
topologyRequestDuration.WithLabelValues(provider, engine, status).Observe(duration.Seconds())
}

func SetMissingTopology(provider, nodename string) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/server/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func processRequest(item interface{}) (interface{}, *HTTPError) {
} else {
code = http.StatusOK
}
metrics.Add(tr.Provider.Name, tr.Engine.Name, code, time.Since(start))
metrics.AddTopologyRequest(tr.Provider.Name, tr.Engine.Name, code, time.Since(start))

return ret, err
}
Expand Down
30 changes: 28 additions & 2 deletions pkg/server/http_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"io"
"net"
"net/http"
"time"

Expand All @@ -45,6 +46,31 @@ func InitHttpServer(ctx context.Context, cfg *config.Config) {
srv = initHttpServer(ctx, cfg)
}

// responseRecorder wraps ResponseWriter to capture status code
type responseRecorder struct {
http.ResponseWriter
statusCode int
}

// Override WriteHeader to capture status code
func (rw *responseRecorder) WriteHeader(code int) {
rw.statusCode = code
rw.ResponseWriter.WriteHeader(code)
}

// LoggingMiddleware logs request/response details
func LoggingMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
rec := &responseRecorder{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(rec, r)
duration := time.Since(start)
from, _, _ := net.SplitHostPort(r.RemoteAddr)
klog.InfoS("HTTP", "method", r.Method, "path", r.URL.Path, "proto", r.Proto, "from", from, "status", rec.statusCode, "duration", duration.Seconds())
metrics.AddHttpRequest(r.Method, r.URL.Path, r.Proto, from, rec.statusCode, duration)
})
}

func initHttpServer(ctx context.Context, cfg *config.Config) *HttpServer {
mux := http.NewServeMux()

Expand All @@ -58,7 +84,7 @@ func initHttpServer(ctx context.Context, cfg *config.Config) *HttpServer {
cfg: cfg,
srv: &http.Server{
Addr: fmt.Sprintf(":%d", cfg.HTTP.Port),
Handler: mux,
Handler: LoggingMiddleware(mux),
},
async: &asyncController{
queue: NewTrailingDelayQueue(processRequest, cfg.RequestAggregationDelay),
Expand Down Expand Up @@ -196,7 +222,7 @@ func getresult(w http.ResponseWriter, r *http.Request) {
}

func httpError(w http.ResponseWriter, provider, engine, msg string, code int, duration time.Duration) *topology.Request {
metrics.Add(provider, engine, code, duration)
metrics.AddTopologyRequest(provider, engine, code, duration)
http.Error(w, msg, code)
return nil
}

0 comments on commit f844abf

Please sign in to comment.