mirror of
https://github.com/siderolabs/omni.git
synced 2025-08-08 02:27:00 +02:00
Omni is source-available under BUSL. Signed-off-by: Andrey Smirnov <andrey.smirnov@siderolabs.com> Co-Authored-By: Artem Chernyshev <artem.chernyshev@talos-systems.com> Co-Authored-By: Utku Ozdemir <utku.ozdemir@siderolabs.com> Co-Authored-By: Dmitriy Matrenichev <dmitry.matrenichev@siderolabs.com> Co-Authored-By: Philipp Sauter <philipp.sauter@siderolabs.com> Co-Authored-By: Noel Georgi <git@frezbo.dev> Co-Authored-By: evgeniybryzh <evgeniybryzh@gmail.com> Co-Authored-By: Tim Jones <tim.jones@siderolabs.com> Co-Authored-By: Andrew Rynhard <andrew@rynhard.io> Co-Authored-By: Spencer Smith <spencer.smith@talos-systems.com> Co-Authored-By: Christian Rolland <christian.rolland@siderolabs.com> Co-Authored-By: Gerard de Leeuw <gdeleeuw@leeuwit.nl> Co-Authored-By: Steve Francis <67986293+steverfrancis@users.noreply.github.com> Co-Authored-By: Volodymyr Mazurets <volodymyrmazureets@gmail.com>
75 lines
1.8 KiB
Go
75 lines
1.8 KiB
Go
// Copyright (c) 2024 Sidero Labs, Inc.
|
|
//
|
|
// Use of this software is governed by the Business Source License
|
|
// included in the LICENSE file.
|
|
|
|
package logging
|
|
|
|
import (
|
|
"net"
|
|
"net/http"
|
|
|
|
"github.com/felixge/httpsnoop"
|
|
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
|
|
grpc_ctxtags "github.com/grpc-ecosystem/go-grpc-middleware/tags"
|
|
"go.uber.org/zap"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// Handler adds structured logging to each request going through a wrapped handler.
|
|
type Handler struct {
|
|
h http.Handler
|
|
logger *zap.Logger
|
|
fields []zap.Field
|
|
}
|
|
|
|
// ServeHTTP implements http.Handler.
|
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
remoteAddr := r.RemoteAddr
|
|
remoteAddr, _, _ = net.SplitHostPort(remoteAddr) //nolint:errcheck
|
|
|
|
if realIP := r.Header.Get("X-Real-IP"); realIP != "" {
|
|
remoteAddr = realIP
|
|
}
|
|
|
|
logger := h.logger.With(
|
|
zap.String("request_url", r.RequestURI),
|
|
zap.String("method", r.Method),
|
|
zap.String("remote_addr", remoteAddr),
|
|
).With(h.fields...)
|
|
|
|
// inject empty ctxtags and logger into request context
|
|
r = r.WithContext(
|
|
ctxzap.ToContext(
|
|
grpc_ctxtags.SetInContext(r.Context(), grpc_ctxtags.NewTags()),
|
|
logger,
|
|
),
|
|
)
|
|
|
|
metrics := httpsnoop.CaptureMetrics(h.h, w, r)
|
|
|
|
// get injected ctxtags back
|
|
ctxtags := grpc_ctxtags.Extract(r.Context()).Values()
|
|
fields := make([]zapcore.Field, 0, len(ctxtags))
|
|
|
|
for k, v := range ctxtags {
|
|
fields = append(fields, zap.Any(k, v))
|
|
}
|
|
|
|
logger.Info("HTTP request done",
|
|
append(
|
|
[]zapcore.Field{
|
|
zap.Duration("duration", metrics.Duration),
|
|
zap.Int("status", metrics.Code),
|
|
zap.Int64("response_length", metrics.Written),
|
|
},
|
|
fields...,
|
|
)...,
|
|
)
|
|
}
|
|
|
|
// NewHandler creates new Handler.
|
|
func NewHandler(h http.Handler, logger *zap.Logger) *Handler {
|
|
return &Handler{h: h, logger: logger}
|
|
}
|