From 6bef30c055519381a2b2db5e84682c8466996326 Mon Sep 17 00:00:00 2001 From: Rahmat Hidayat Date: Thu, 2 May 2024 17:32:29 +0700 Subject: [PATCH] chore(sever): add http_path field in request log (#148) --- internal/server/{auth.go => interceptors.go} | 30 ++++++++++++++++---- internal/server/server.go | 5 ++-- 2 files changed, 27 insertions(+), 8 deletions(-) rename internal/server/{auth.go => interceptors.go} (57%) diff --git a/internal/server/auth.go b/internal/server/interceptors.go similarity index 57% rename from internal/server/auth.go rename to internal/server/interceptors.go index 915feff0e..e93a13570 100644 --- a/internal/server/auth.go +++ b/internal/server/interceptors.go @@ -2,6 +2,7 @@ package server import ( "context" + "net/http" ctx_logrus "github.com/grpc-ecosystem/go-grpc-middleware/tags/logrus" "github.com/sirupsen/logrus" @@ -11,9 +12,13 @@ import ( type authenticatedUserEmailContextKey struct{} -var logrusActorKey = "actor" +const ( + logrusActorKey = "actor" -func withAuthenticatedUserEmail(headerKey string) grpc.UnaryServerInterceptor { + grpcgatewayHTTPPathKey = "http-path" +) + +func headerAuthInterceptor(headerKey string) grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { if md, ok := metadata.FromIncomingContext(ctx); ok { if v := md.Get(headerKey); len(v) > 0 { @@ -26,14 +31,27 @@ func withAuthenticatedUserEmail(headerKey string) grpc.UnaryServerInterceptor { } } -func withLogrusContext() grpc.UnaryServerInterceptor { +func enrichRequestMetadata(ctx context.Context, req *http.Request) metadata.MD { + return metadata.New(map[string]string{ + grpcgatewayHTTPPathKey: req.URL.Path, + }) +} + +func enrichLogrusFields() grpc.UnaryServerInterceptor { return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + fields := make(logrus.Fields, 0) + if userEmail, ok := ctx.Value(authenticatedUserEmailContextKey{}).(string); ok { - ctx_logrus.AddFields(ctx, logrus.Fields{ - logrusActorKey: userEmail, - }) + fields[logrusActorKey] = userEmail } + if md, ok := metadata.FromIncomingContext(ctx); ok { + fields["http_path"] = md[grpcgatewayHTTPPathKey][0] + } + + if len(fields) > 0 { + ctx_logrus.AddFields(ctx, fields) + } return handler(ctx, req) } } diff --git a/internal/server/server.go b/internal/server/server.go index 1f89e48a8..9e63e45ca 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -93,7 +93,7 @@ func RunServer(config *Config) error { ), grpc_logrus.UnaryServerInterceptor(logrusEntry), authInterceptor, - withLogrusContext(), + enrichLogrusFields(), otelgrpc.UnaryServerInterceptor(), )), ) @@ -134,6 +134,7 @@ func RunServer(config *Config) error { DiscardUnknown: true, }, }), + runtime.WithMetadata(enrichRequestMetadata), ) // grpcPort has to be same as config.Port till the time guardian service can support both grpc and http in two different ports @@ -216,7 +217,7 @@ func makeHeaderMatcher(c *Config) func(key string) (string, bool) { func getAuthInterceptor(config *Config) (grpc.UnaryServerInterceptor, error) { // default fallback to user email on header - authInterceptor := withAuthenticatedUserEmail(config.Auth.Default.HeaderKey) + authInterceptor := headerAuthInterceptor(config.Auth.Default.HeaderKey) if config.Auth.Provider == "oidc" { idtokenValidator, err := idtoken.NewValidator(context.Background())