100 lines
2.5 KiB
Go
100 lines
2.5 KiB
Go
package gapi
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/http"
|
|
"time"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
func GrpcLogger(
|
|
ctx context.Context,
|
|
req interface{},
|
|
info *grpc.UnaryServerInfo,
|
|
handler grpc.UnaryHandler,
|
|
) (resp interface{}, err error) {
|
|
startTime := time.Now()
|
|
result, err := handler(ctx, req)
|
|
duration := time.Since(startTime)
|
|
|
|
statusCode := codes.Unknown
|
|
if st, ok := status.FromError(err); ok {
|
|
statusCode = st.Code()
|
|
}
|
|
|
|
if err != nil {
|
|
slog.Error("received a gRPC request",
|
|
slog.String("protocol", "grpc"),
|
|
slog.String("endpoint", info.FullMethod),
|
|
slog.Int("status_code", int(statusCode)),
|
|
slog.String("status_text", statusCode.String()),
|
|
slog.Duration("duration", duration),
|
|
slog.String("error", err.Error()),
|
|
)
|
|
} else {
|
|
slog.Info("received a gRPC request",
|
|
slog.String("protocol", "grpc"),
|
|
slog.String("endpoint", info.FullMethod),
|
|
slog.Int("status_code", int(statusCode)),
|
|
slog.String("status_text", statusCode.String()),
|
|
slog.Duration("duration", duration),
|
|
)
|
|
}
|
|
|
|
return result, err
|
|
}
|
|
|
|
type ResponseRecorder struct {
|
|
http.ResponseWriter
|
|
StatusCode int
|
|
Body []byte
|
|
}
|
|
|
|
func (rec *ResponseRecorder) WriteHeader(statusCode int) {
|
|
rec.StatusCode = statusCode
|
|
rec.ResponseWriter.WriteHeader(statusCode)
|
|
}
|
|
|
|
func (rec *ResponseRecorder) Write(body []byte) (int, error) {
|
|
rec.Body = body
|
|
return rec.ResponseWriter.Write(body)
|
|
}
|
|
|
|
func HttpLogger(handler http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
|
|
startTime := time.Now()
|
|
rec := &ResponseRecorder{
|
|
ResponseWriter: res,
|
|
StatusCode: http.StatusOK,
|
|
}
|
|
|
|
handler.ServeHTTP(rec, req)
|
|
duration := time.Since(startTime)
|
|
|
|
if rec.StatusCode != http.StatusOK {
|
|
slog.Error("received a HTTP request",
|
|
slog.String("protocol", "http"),
|
|
slog.String("method", req.Method),
|
|
slog.String("endpoint", req.RequestURI),
|
|
slog.Int("status_code", rec.StatusCode),
|
|
slog.String("status_text", http.StatusText(rec.StatusCode)),
|
|
slog.Duration("duration", duration),
|
|
slog.String("body", string(rec.Body)),
|
|
)
|
|
} else {
|
|
slog.Info("received a HTTP request",
|
|
slog.String("protocol", "http"),
|
|
slog.String("method", req.Method),
|
|
slog.String("endpoint", req.RequestURI),
|
|
slog.Int("status_code", rec.StatusCode),
|
|
slog.String("status_text", http.StatusText(rec.StatusCode)),
|
|
slog.Duration("duration", duration),
|
|
)
|
|
}
|
|
})
|
|
}
|