- bridge: SetMaxReconnectInterval(30с) — дефолт ~10м слишком долог для телеметрии. - logging middleware: /health,/healthz,/ready → Debug (не засорять лог). - processor: 'telemetry buffered' вместо Info 'saved' (данные ещё буферизованы).
43 lines
1.3 KiB
Go
43 lines
1.3 KiB
Go
// Package middleware — HTTP-промежуточные слои API.
|
|
package middleware
|
|
|
|
import (
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
)
|
|
|
|
// responseWriter перехватывает статус ответа для логирования.
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
status int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(code int) {
|
|
rw.status = code
|
|
rw.ResponseWriter.WriteHeader(code)
|
|
}
|
|
|
|
// Logging логирует каждый HTTP-запрос: метод, путь, статус, длительность.
|
|
func Logging(log *slog.Logger, next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
rw := &responseWriter{ResponseWriter: w, status: http.StatusOK}
|
|
next.ServeHTTP(rw, r)
|
|
// Пробы здоровья логируем на Debug: платформа опрашивает их часто, а
|
|
// Info-строка на каждую засоряет лог (ревью 2026-10-10).
|
|
level := slog.LevelInfo
|
|
switch r.URL.Path {
|
|
case "/health", "/healthz", "/ready":
|
|
level = slog.LevelDebug
|
|
}
|
|
log.Log(r.Context(), level, "http",
|
|
"method", r.Method,
|
|
"path", r.URL.Path,
|
|
"status", rw.status,
|
|
"duration_ms", time.Since(start).Milliseconds(),
|
|
"remote", r.RemoteAddr,
|
|
)
|
|
})
|
|
}
|