Skip to content

feat: add context providers to logging integrations - #1417

Open
giortzisg wants to merge 1 commit into
scopes/integration-primitivesfrom
scopes/logging-integrations-context
Open

giortzisg wants to merge 1 commit into
scopes/integration-primitivesfrom
scopes/logging-integrations-context

Conversation

@giortzisg

Copy link
Copy Markdown
Contributor

Description

Issues

Changelog Entry Instructions

To add a custom changelog entry, uncomment the section above. Supports:

  • Single entry: just write text
  • Multiple entries: use bullet points
  • Nested bullets: indent 4+ spaces

For more details: custom changelog entries

Reminders

Stack created with GitHub Stacks CLIGive Feedback 💬

Comment thread slog/sentryslog.go

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread logrus/logrusentry.go Outdated
Comment thread logrus/logrusentry.go Outdated
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from 63cc4df to d644ba0 Compare September 4, 2026 13:26
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from d644ba0 to bf8948b Compare September 7, 2026 11:40
Comment thread zerolog/sentryzerolog.go Outdated
Comment thread zerolog/sentryzerolog.go
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from bf8948b to ceeb3d8 Compare September 7, 2026 11:49

@szokeasaurusrex szokeasaurusrex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly lgtm, but I noticed some small things likely worth addressing

Comment thread logrus/logrusentry.go Outdated
Comment on lines 76 to 88
func (h *logHook) SetHubProvider(provider func() *sentry.Hub) {
h.hubProvider = provider
h.useCustomProvider = true
if provider == nil {
h.SetContextProvider(nil)
return
}
h.SetContextProvider(func() context.Context {
hub := provider()
if hub == nil {
return nil
}
return sentry.SetHubOnContext(context.Background(), hub)
})
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: Why is this still needed if we are getting rid of hubs?

Is it just to satisfy the Hook interface, and if yes, why not just break that interface in this PR?

Comment thread logrus/logrusentry.go
Comment on lines 224 to +226
func (h *logHook) FlushWithContext(ctx context.Context) bool {
return h.hubProvider().Client().FlushWithContext(ctx)
return sentry.ClientFromContext(h.providerContext()).FlushWithContext(ctx)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

[question] in what case would someone want to use this API?

It seems confusing to have two different contexts. What is the difference between the two contexts and how they are used?

Comment thread logrus/logrusentry_test.go Outdated
Comment on lines +138 to +150
func TestLogHookContextProviderHonorsExplicitNoopClient(t *testing.T) {
defaultClient, defaultTransport := setupClientTest()
ctx, _ := sentry.WithIsolationScope(context.Background())
ctx = sentry.ContextWithClient(ctx, sentry.NewNoopClient())

hook := NewLogHookFromClient([]logrus.Level{logrus.InfoLevel}, defaultClient)
hook.SetContextProvider(func() context.Context { return ctx })

err := hook.Fire(&logrus.Entry{Level: logrus.InfoLevel, Message: "suppressed"})
assert.NoError(t, err)
assert.True(t, defaultClient.Flush(testutils.FlushTimeout()))
assert.Empty(t, defaultTransport.Events())
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: I am skeptical we need this test.

At least as far as I can tell, there is no notion of a "global default" Sentry client in Go, at least not after these changes.

So, it is therefore a bit strange to test that a Logrus hook set up with a no-op client would then record events on a totally unrelated test client; even if this client is the default client for tests, it is not a true global default.

It is possible I am missing something, and in that case, I would appreciate if you can let me know where my reasoning is wrong. If I am right, my recommendation would be either to completely remove this test, or to instead narrow it a bit just to check that the logrus hook can be initialized with a no-op client successfully, without then asserting another unrelated client's behavior.

Comment thread zerolog/sentryzerolog.go Outdated
Comment on lines +260 to +263
func contextWithClient(client *sentry.Client) context.Context {
ctx := sentry.ContextWithScope(context.Background(), sentry.NewScope())
return sentry.ContextWithClient(ctx, client)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: I would rename this function to indicate more clearly the difference versus sentry.ContextWithClient (i.e. that a new scope is also created).

Suggested change
func contextWithClient(client *sentry.Client) context.Context {
ctx := sentry.ContextWithScope(context.Background(), sentry.NewScope())
return sentry.ContextWithClient(ctx, client)
}
func contextWithClientAndNewScope(client *sentry.Client) context.Context {
ctx := sentry.ContextWithScope(context.Background(), sentry.NewScope())
return sentry.ContextWithClient(ctx, client)
}

Although as far as I can tell, the function is only used in one place, so you could also consider removing it.

Comment thread zerolog/sentryzerolog.go Outdated
Comment on lines +145 to +152
// NewWithHub creates a writer using an existing sentry Hub and options.
func NewWithHub(hub *sentry.Hub, opts Options) (*Writer, error) {
if hub == nil {
return nil, errors.New("hub cannot be nil")
}
return NewWithContext(sentry.SetHubOnContext(context.Background(), hub), opts)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

m: This appears to be unused; I am somewhat surprised that there is not a linter to catch this (or perhaps I am mistaken)

Suggested change
// NewWithHub creates a writer using an existing sentry Hub and options.
func NewWithHub(hub *sentry.Hub, opts Options) (*Writer, error) {
if hub == nil {
return nil, errors.New("hub cannot be nil")
}
return NewWithContext(sentry.SetHubOnContext(context.Background(), hub), opts)
}

Comment on lines +59 to 60
_, err = NewWithContext(nil, Options{}) // nolint: staticcheck // nil validation
require.NotNil(t, err)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

l: I am guessing the linter would catch such a case (that's why we suppress it), and if so, why do we need to test it here?

@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from ceeb3d8 to 7b8a3a5 Compare September 16, 2026 09:14

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 7b8a3a5. Configure here.

Comment thread zap/sentryzap.go
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from 7b8a3a5 to 939f803 Compare September 17, 2026 08:38
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from 939f803 to 0f80bc5 Compare September 17, 2026 09:09
Route Logrus, Slog, Zap, and Zerolog through context-backed clients and scopes while retaining Hub compatibility until final removal. Rely on the core logger fallback instead of adapter-specific background and provider state.

Resolve Logrus and Zap flush clients with the same context fallback as emission, including explicit disabled clients. Clarify flush cancellation versus capture routing and remove the redundant Zerolog context helper.
@giortzisg
giortzisg removed this pull request from stack #1420 September 18, 2026 11:17
@giortzisg
giortzisg force-pushed the scopes/logging-integrations-context branch from 0f80bc5 to d7d1275 Compare September 18, 2026 11:18
@giortzisg
giortzisg added this pull request to stack #1433 September 18, 2026 11:22
Comment thread logrus/logrusentry.go
Comment on lines +219 to +222
}
if h.contextProvider != nil {
if ctx := h.contextProvider(); ctx != nil {
return ctx

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: When a contextProvider is set, resolveContext discards the existing entry.Context, causing the loss of per-request data like trace spans added via log.WithContext(requestCtx).
Severity: MEDIUM

Suggested Fix

Modify resolveContext to use the entry.Context as the base and merge it with the context from the contextProvider. This ensures that per-request information, like trace spans, is preserved instead of being completely replaced by the provider's context.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: logrus/logrusentry.go#L219-L222

Potential issue: When a `contextProvider` is set, the `resolveContext` function returns
the context from the provider directly, completely discarding the existing
`entry.Context`. This is a regression from the previous behavior which used
`entry.Context` as the base. As a result, users who pass request-specific contexts using
`log.WithContext(requestCtx)` will find that important data, such as tracing spans, is
silently dropped from the logs, hindering observability and debugging.

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.

2 participants