Skip to content

Commit

Permalink
Add request id to logs.
Browse files Browse the repository at this point in the history
This change adds a GRPC interceptor that fetches the header
`Grpc-Metadata-Request-Id` and adds it to the logger. It also returns
the request id to the client in the trailer, which is helpful for
debugging.

CLI command `minder history list` was modified to show its usage, but
those changes should be reverted.
  • Loading branch information
blkt committed Oct 2, 2024
1 parent 15fd53d commit 4c55b9b
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions internal/controlplane/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ func (s *Server) StartGRPCServer(ctx context.Context) error {
// TODO: this has no test coverage!
util.SanitizingInterceptor(),
logger.Interceptor(s.cfg.LoggingConfig),
logger.RequestIDInterceptor(),
TokenValidationInterceptor,
EntityContextProjectInterceptor,
ProjectAuthorizationInterceptor,
Expand Down
43 changes: 43 additions & 0 deletions internal/logger/logging_interceptor.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"path"
"time"

"github.com/google/uuid"
"github.com/rs/zerolog"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
Expand Down Expand Up @@ -101,3 +102,45 @@ func Interceptor(cfg config.LoggingConfig) grpc.UnaryServerInterceptor {
return resp, err
}
}

// RequestIDInterceptor traces request ids.
//
// It tries to use the request id from the request context, creating a
// new one if that is missing. It also sends back in the trailer the
// request id, ensuring that the client receives it.
func RequestIDInterceptor() grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, _ *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
rID := maybeGetRequestID(ctx)
ctx = zerolog.Ctx(ctx).With().Str("request_id", rID).Logger().WithContext(ctx)

resp, err := handler(ctx, req)

if err := grpc.SetTrailer(ctx, metadata.Pairs("request-id", rID)); err != nil {
zerolog.Ctx(ctx).Trace().Err(err).Msg("unable to attach request id to trailer")
}

return resp, err
}
}

func maybeGetRequestID(ctx context.Context) string {
var rID string
if md, ok := metadata.FromIncomingContext(ctx); ok {
if rIDs, ok := md["request-id"]; ok {
if len(rIDs) != 0 {
rID = rIDs[0]
}
}
}

if rID == "" {
return uuid.New().String()
}

if _, err := uuid.Parse(rID); err != nil {
zerolog.Ctx(ctx).Trace().Err(err).Msg("request id is not valid uuid")
return uuid.New().String()
}

return rID
}

0 comments on commit 4c55b9b

Please sign in to comment.