Skip to content

contrib(zap): add log/trace correlation for uber-go/zap#4610

Open
highlyavailable wants to merge 6 commits intoDataDog:mainfrom
highlyavailable:feat/contrib-zap-log-correlation
Open

contrib(zap): add log/trace correlation for uber-go/zap#4610
highlyavailable wants to merge 6 commits intoDataDog:mainfrom
highlyavailable:feat/contrib-zap-log-correlation

Conversation

@highlyavailable
Copy link
Copy Markdown

@highlyavailable highlyavailable commented Mar 27, 2026

What does this PR do?

Adds a new contrib package at contrib/go.uber.org/zap that provides log/trace correlation for uber-go/zap. Just the single helper TraceFields(ctx context.Context) []zap.Field which pulls DD trace and span IDs from the context and returns them as zap fields.

Usage:

logger.Info("completed request", ddzap.TraceFields(ctx)...)

Zap's zapcore.Core.Write() doesn't take context.Context, wrapping the core didn't seem like an option, but I am happy to get your feedback if you can think of a better implementation.

I added support for both 128-bit and 64-bit trace ID formats via DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED.

Motivation

go.uber.org/zap is one of the most widely used structured loggers in Go and there's currently no Datadog logging integration for it. This closes that gap, following the same patterns used by the existing zerolog and logrus contribs.

@highlyavailable highlyavailable requested review from a team as code owners March 27, 2026 02:22
@darccio
Copy link
Copy Markdown
Member

darccio commented Mar 27, 2026

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@darccio
Copy link
Copy Markdown
Member

darccio commented Mar 27, 2026

@highlyavailable Thanks for contributing it! It'd be great if you can add an orchestrion.yml definition file to allow you to use Orchestrion too. If it's too much, we can take care of that.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 60.73%. Comparing base (92711d0) to head (e137493).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
Files with missing lines Coverage Δ
instrumentation/packages.go 7.81% <ø> (-1.57%) ⬇️

... and 265 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@darccio
Copy link
Copy Markdown
Member

darccio commented Mar 27, 2026

@highlyavailable Check the CI checks, as there are some failing.

@highlyavailable highlyavailable requested a review from a team as a code owner March 27, 2026 13:48
highlyavailable and others added 4 commits March 27, 2026 07:56
Add PackageGoUberOrgZap constant and PackageInfo entry to prepare
for the upcoming uber-go/zap logging contrib integration.
Add contrib/go.uber.org/zap with a TraceFields helper that extracts
Datadog trace and span IDs from context and returns them as zap fields.
Supports both 128-bit and 64-bit trace ID formats.

Usage: logger.Info("msg", ddzap.TraceFields(ctx)...)
Add go.uber.org/zap to the contribIntegrations map in tracer/option.go
so it shows up in startup diagnostics. Also add the package to
supported_integrations.md and update go.work.sum.
Adds an orchestrion.yml that marks go.uber.org/zap as imported when
Orchestrion auto-instrumentation is active. Full automatic context
injection isn't possible since zap's zapcore.Core.Write() doesn't
accept context.Context, but integration discovery is handled.
@highlyavailable highlyavailable force-pushed the feat/contrib-zap-log-correlation branch from 9895fa7 to 6a25ead Compare March 27, 2026 13:56
@highlyavailable
Copy link
Copy Markdown
Author

highlyavailable commented Mar 27, 2026

@highlyavailable Thanks for contributing it! It'd be great if you can add an orchestrion.yml definition file to allow you to use Orchestrion too. If it's too much, we can take care of that.

Hi @darccio, I added a commit with an orchestrion.yml file. I tried to follow other examples in the repo.

@highlyavailable Check the CI checks, as there are some failing.

Made some updates for the failing CI checks, waiting on the approval now 👍

@darccio
Copy link
Copy Markdown
Member

darccio commented Mar 27, 2026

@highlyavailable Thanks. I'll let @DataDog/apm-idm-go to discuss the implementation design.

About the orchestrion.yml, I think we need to investigate a bit more, because your implementation requires targeting the arguments of any logging method - like Info - and prepending TraceFields(ctx) and the ctx value should be captured from the function or introduced by a //dd:span directive on the function.

@darccio
Copy link
Copy Markdown
Member

darccio commented Mar 27, 2026

BTW, we had another implementation in progress #4241 cc @quinna-h

Was failing CI jobs, after reading through their logs I think I need to set the integration count (56 → 57) and register
DD_TRACE_ZAP_ANALYTICS_ENABLED as a supported config
@highlyavailable highlyavailable requested a review from a team as a code owner April 6, 2026 00:26
@highlyavailable
Copy link
Copy Markdown
Author

Hi @darccio. Just pushed an update to tests and config which should take care of the failing CI.

For orchestrion.yml, what’s in there right now is just wiring up integration telemetry. I wasn’t really sure about the best way to handle actual trace injection given zap’s constraints, so would really appreciate any guidance on how you (or others) all think that should be done.

Also saw the overlap with #4241, main difference is I went with TraceFields(ctx) []zap.Field returning raw fields instead of wrapping the logger, since that felt more in line with how zap is usually used (IME). I left out the WrapCore wrapper for now since it wasn’t doing anything yet.

That said, I’m very open to aligning with #4241 or reshaping the API if you have a preferred direction, happy to adjust and thank you for the feedback so far

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