Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add request id to logs. #4461

Merged
merged 2 commits into from
Oct 16, 2024
Merged

Add request id to logs. #4461

merged 2 commits into from
Oct 16, 2024

Conversation

blkt
Copy link
Contributor

@blkt blkt commented Sep 12, 2024

Summary

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 header, which is helpful for debugging.

Fixes #4611

Change Type

  • Bug fix (resolves an issue without affecting existing features)
  • Feature (adds new functionality without breaking changes)
  • Breaking change (may impact existing functionalities or require documentation updates)
  • Documentation (updates or additions to documentation)
  • Refactoring or test improvements (no bug fixes or new functionality)

Testing

Manual tests.

Review Checklist:

  • Reviewed my own code for quality and clarity.
  • Added comments to complex or tricky code sections.
  • Updated any affected documentation.
  • Included tests that validate the fix or feature.
  • Checked that related changes are merged.

@blkt blkt self-assigned this Sep 12, 2024
@coveralls
Copy link

coveralls commented Sep 12, 2024

Coverage Status

coverage: 53.045% (-0.06%) from 53.105%
when pulling 4c55b9b on enh/request-id-interceptor
into 15fd53d on main.

@blkt blkt force-pushed the enh/request-id-interceptor branch 2 times, most recently from 71d4a69 to 9d1d981 Compare September 12, 2024 08:42
@blkt blkt changed the title Log request id to all messages. Add request id to logs. Sep 12, 2024
@blkt blkt marked this pull request as ready for review September 12, 2024 08:42
func maybeGetRequestID(ctx context.Context) string {
var rID string
if md, ok := metadata.FromIncomingContext(ctx); ok {
if rIDs, ok := md["request-id"]; ok {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in HTTP what would this translate to? I wonder how it works with the HTTP gateway we use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GRPC moves back and forth headers having prefix Grpc-Metadata-, so it would become Grpc-Metadata-Request-Id.

@evankanderson
Copy link
Member

evankanderson commented Sep 17, 2024

@blkt blkt marked this pull request as draft September 19, 2024 11:27
@blkt
Copy link
Contributor Author

blkt commented Oct 2, 2024

@evankanderson while estimating work to improve logging I had a look at the documents you linked. My take is that the capabilities described in those specs far exceed our current need, which is to track a request execution from start to finish in logs.

My take is that we're better off polishing this work, possibly changing the header's key (not the value), and merge it.

@evankanderson
Copy link
Member

@evankanderson while estimating work to improve logging I had a look at the documents you linked. My take is that the capabilities described in those specs far exceed our current need, which is to track a request execution from start to finish in logs.

My take is that we're better off polishing this work, possibly changing the header's key (not the value), and merge it.

Sounds good; I'd thought this would be something like:

import "go.opentelemetry.io/otel/trace"

// ...
sc := trace.SpanContextFromContext(ctx)
ctx = zerolog.Ctx(ctx).With().Str("trace_id", sc.TraceID()).Logger().WithContext(ctx)

If there's a bunch more content, then I'd agree on doing our own thing.

@blkt blkt force-pushed the enh/request-id-interceptor branch from 8111143 to 4c55b9b Compare October 2, 2024 16:15
@blkt blkt force-pushed the enh/request-id-interceptor branch from 4c55b9b to fc6777b Compare October 15, 2024 12:27
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.
@blkt blkt force-pushed the enh/request-id-interceptor branch from fc6777b to f804097 Compare October 15, 2024 12:28
@blkt blkt marked this pull request as ready for review October 15, 2024 12:28
@blkt
Copy link
Contributor Author

blkt commented Oct 15, 2024

Here is an example of the output

curl -v -H "Authorization: Bearer $TOKEN" 'http://localhost:8080/api/v1/user'
> GET /api/v1/user HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.7.1
> Accept: */*
> Authorization: Bearer xxx
>
* Request completely sent off
< HTTP/1.1 200 OK
< Content-Length: 933
< Content-Type: application/json
< Grpc-Metadata-Content-Type: application/grpc
< Grpc-Metadata-Request-Id: 062ff9f8-e94a-4742-8cc1-8c07b817c286
< Date: Tue, 15 Oct 2024 12:33:20 GMT
<
* Connection #0 to host localhost left intact
* ...

Logs would be like this

{"level":"info","Resource":{"service":"minder.v1.UserService","method":"GetUser"},"request_id":"062ff9f8-e94a-4742-8cc1-8c07b817c286","caller":"/Users/michelangelo/stacklok/minder/internal/controlplane/handlers_authz.go:60","Timestamp":1728995600029354000,"message":"Bypassing setting up context"}
{"level":"info","Resource":{"service":"minder.v1.UserService","method":"GetUser"},"request_id":"062ff9f8-e94a-4742-8cc1-8c07b817c286","caller":"/Users/michelangelo/stacklok/minder/internal/controlplane/handlers_authz.go:86","Timestamp":1728995600029372000,"message":"Bypassing project authorization"}

Using Grpc-Metadata- prefix gets us the least amount of changes to the codebase while still getting the result, but we could write our own matcher for the header.

@coveralls
Copy link

coveralls commented Oct 15, 2024

Pull Request Test Coverage Report for Build 11351156474

Details

  • 0 of 14 (0.0%) changed or added relevant lines in 2 files are covered.
  • 2 unchanged lines in 1 file lost coverage.
  • Overall coverage decreased (-0.04%) to 54.468%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/controlplane/server.go 0 3 0.0%
internal/logger/logging_interceptor.go 0 11 0.0%
Files with Coverage Reduction New Missed Lines %
internal/eea/eea.go 2 73.73%
Totals Coverage Status
Change from base Build 11344831838: -0.04%
Covered Lines: 14929
Relevant Lines: 27409

💛 - Coveralls

Also, use header rather than trailer.
@blkt blkt force-pushed the enh/request-id-interceptor branch from f804097 to f2b1f94 Compare October 15, 2024 17:21
Copy link
Contributor

@jhrozek jhrozek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good start, I see the result both on the server side in the middleware and the client side in the headers (verified with curl).

Regarding the server vs client side headers - what if we had another header like e.g. Request-Correlation-ID that the client could set in case a single client operation performs multiple requests? In that case the client might set the correlation to request ID of the first operation. There would be still the unique request ID and the correlation would really be just a hint for easier search of requests in the logs?

@evankanderson
Copy link
Member

I think this is a good start, I see the result both on the server side in the middleware and the client side in the headers (verified with curl).

Regarding the server vs client side headers - what if we had another header like e.g. Request-Correlation-ID that the client could set in case a single client operation performs multiple requests? In that case the client might set the correlation to request ID of the first operation. There would be still the unique request ID and the correlation would really be just a hint for easier search of requests in the logs?

I'd wait here for a "bigger" tracing solution, and then have the top-level command use some sort of trace-parent to correlate the requests.

One thing that may not be obvious here, but it looks like the request_id header won't pass through any usages of watermill or other asynchronous processing. I think that's fine for now, but it's worth being aware of given how much async processing we do.

@blkt
Copy link
Contributor Author

blkt commented Oct 16, 2024

Regarding the server vs client side headers - what if we had another header like e.g. Request-Correlation-ID that the client could set in case a single client operation performs multiple requests?

I agree with @evankanderson in this, tracing across multiple requests requires some amount of shared state and more changes to the codebase. This is just a helper to filter down logs quickly.

One thing that may not be obvious here, but it looks like the request_id header won't pass through any usages of watermill or other asynchronous processing.

That's correct, for that case we already track Github's delivery id that sort-of solves the same problem.
https://github.com/mindersec/minder/blob/main/internal/providers/github/webhook/hook.go#L127
https://github.com/mindersec/minder/blob/main/internal/providers/github/webhook/app.go#L151
We might want to spend some effort ensuring this is logged correctly downstream watermill. I'll create a task.

@blkt blkt merged commit e4f47e8 into main Oct 16, 2024
18 of 19 checks passed
@blkt blkt deleted the enh/request-id-interceptor branch October 16, 2024 10:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Trace request ids across RPC calls
5 participants