fix: [#946] stop WithContext from leaking framework context keys#1456
Conversation
5f0c670 to
6054e49
Compare
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1456 +/- ##
==========================================
+ Coverage 69.25% 69.30% +0.04%
==========================================
Files 367 367
Lines 28890 28949 +59
==========================================
+ Hits 20007 20062 +55
- Misses 7985 7987 +2
- Partials 898 900 +2 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Pull request overview
Stops WithContext log output from leaking framework-internal context keys by introducing default context-key filtering and an optional user-configurable exclude list.
Changes:
- Added a default denylist of framework-internal context keys and a helper to filter context values before logging.
- Updated
IOHandlertext/JSON formatting to use the filtered context map. - Expanded unit tests to verify default filtering behavior, typed-string key matching, and user-specified excludes.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| log/logger/utils.go | Adds default excluded keys and filterContextValues; refactors context extraction. |
| log/logger/handler.go | Centralizes context extraction + filtering via contextValues() and applies it to text/JSON output. |
| log/logger/utils_test.go | Adds focused tests for context filtering behavior and key stringification. |
| log/logger/handler_test.go | Adds integration-style handler tests to ensure filtering works in emitted logs. |
| log/writer_test.go | Updates WithContext expectations to assert secrets/framework keys are not written. |
| utilsContextKey("locale"): "fr", | ||
| "request_id": "req-1", | ||
| }, | ||
| expect: map[string]any{"request_id": "req-1"}, |
There was a problem hiding this comment.
The string locale is excepted as default, not utilsContextKey("locale"). Is it acceptable to log utilsContextKey("locale") here?
There was a problem hiding this comment.
Filter matches by label form, not by exact type. So utilsContextKey("locale") produces label locale and hits the default. If you'd rather match by exact type, we'd need each framework package to export its sentinel.
There was a problem hiding this comment.
Sorry, what's the meaning of each framework package to export its sentinel? For example?
There was a problem hiding this comment.
If the keys collide, we either expose the key type so values don't collide, or match by the string value. Say I set the locale key as a struct localeType. Since it's internal to the package, you can't pass []any{localeType{}} in the config to exclude it, so you'd have to use the value "locale" instead. So either we export LocalType, or we keep matching by value.
That said, in this case I don't think we need to filter locale by default. It's small and not noisy.
There was a problem hiding this comment.
Hence, are framework.utilsContextKey("locale") in the configuration and utilsContextKey("locale") in the framework internal different?
There was a problem hiding this comment.
Yes, it’s the same value. If the framework exports the type, then creating framework.utilsContextKey("locale") in user config gives you the same key as the one used internally. Since both the type and value match, they compare equal and work fine as map keys.
hwbrzzl
left a comment
There was a problem hiding this comment.
LGTM, please solve the conflict.
* origin/master: fix(ai): remove context from image response content (goravel#1462) feat(ai): support provider-managed files (goravel#1460) feat(ai): add image generation support (goravel#1461) fix: [goravel#946] stop WithContext from leaking framework context keys (goravel#1456) feat(ai): add attachment upload support (goravel#1459) feat(ai): add attachment helper subpackages (goravel#1458) feat(ai): switch OpenAI provider to responses API (goravel#1457) feat(ai): add attachment support (goravel#1455)


📑 Description
Closes goravel/goravel#946
facades.Log().WithContext(ctx)was reflecting over the context and dumping every key/value, leakingGoravelAuthJwtand any other framework-internal values into logs. This filters the dump instead of removing it (the propagation use case from #282 still works).Behavior
GoravelAuthJwt,goravel_http_client_name.logging.context.excludeconfig ([]any) extends it. Not added to the default config stub — opt-in via docs.Matching rules
Two matchers run per key:
==): for non-string[]anyconfig entries, e.g.[]any{middleware.PanicTest{}}.shortNamefirst, then itsqualifiedName.shortName(k)returns the underlying string for string-kind keys and%T(e.g.pkg.Type) for everything else.qualifiedName(k)returns the import-path-qualified type (github.com/.../pkg.Type).Output labels
pkg.Typeform by default; if two keys would share the same short form (same package name in different modules), only the colliding ones escalate to fully-qualified import paths. Non-colliding keys keep the short form.Notes
sync.Once; runtime hot-swaps are not picked up.✅ Checks