Skip to content

feat(otel): add otel logs support#5446

Merged
mabdinur merged 23 commits into
masterfrom
munir/implement-otel-logs
May 15, 2026
Merged

feat(otel): add otel logs support#5446
mabdinur merged 23 commits into
masterfrom
munir/implement-otel-logs

Conversation

@mabdinur

@mabdinur mabdinur commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds OpenTelemetry logs support to dd-trace-rb, mirroring the existing metrics signal integration. When enabled, the library configures an OpenTelemetry::SDK::Logs::LoggerProvider backed by an OTLP exporter (http/protobuf) and wires it into the global OTel SDK. Datadog's log_injection is automatically disabled to prevent duplicate trace-correlation fields in log output.

Also extracts a shared SignalConfiguration module (included by both Logs and Metrics) to eliminate verbatim duplication of the OTel resource-building and config-fallback logic.

Motivation:

Customers using OpenTelemetry in Ruby applications can already export traces and metrics through Datadog's OTel-compatible pipeline; this PR closes the remaining gap for logs.

Change log entry

Yes. Added OpenTelemetry logs support. When DD_LOGS_OTEL_ENABLED=true, the library configures an OTLP log exporter that sends log records to the Datadog Agent (or any OTLP endpoint) and automatically disables Datadog log injection to avoid duplicate trace-correlation fields.

Configuration

The following environment variables are newly supported:

Variable Default Notes
DD_LOGS_OTEL_ENABLED false Master toggle — must be true to activate OTel logs
OTEL_LOGS_EXPORTER otlp Set to none to disable the exporter without disabling the SDK
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT http://<agent>:4318/v1/logs Signal-specific endpoint; falls back to OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_EXPORTER_OTLP_LOGS_HEADERS Signal-specific headers; falls back to OTEL_EXPORTER_OTLP_HEADERS
OTEL_EXPORTER_OTLP_LOGS_TIMEOUT 10000 ms Signal-specific timeout; falls back to OTEL_EXPORTER_OTLP_TIMEOUT
OTEL_BLRP_MAX_QUEUE_SIZE 2048 Batch log record processor queue size
OTEL_BLRP_SCHEDULE_DELAY 1000 ms Batch processor flush interval
OTEL_BLRP_EXPORT_TIMEOUT 30000 ms Batch processor export timeout
OTEL_BLRP_MAX_EXPORT_BATCH_SIZE 512 Max records per export batch

Requires Ruby >= 3.1 and the opentelemetry-logs-sdk + opentelemetry-exporter-otlp-logs gems.

Additional Notes:

The SignalConfiguration module refactor is a pure internal change with no public API impact — both Logs and Metrics include it and the extracted methods were previously private.

How to test the change?

bundle exec rake test:opentelemetry

Integration: enable DD_LOGS_OTEL_ENABLED=true with a running Datadog Agent (OTLP receiver on port 4318) and emit log records via the OTel Ruby SDK — records appear in Datadog Log Management with trace correlation.

@github-actions github-actions Bot added core Involves Datadog core libraries otel OpenTelemetry-related changes labels Mar 12, 2026
@github-actions

github-actions Bot commented Mar 12, 2026

Copy link
Copy Markdown

Thank you for updating Change log entry section 👏

Visited at: 2026-05-13 15:13:37 UTC

@mabdinur mabdinur changed the title feat(otel): add otel logs support [WIP] feat(otel): add otel logs support Mar 12, 2026
@github-actions

github-actions Bot commented Mar 12, 2026

Copy link
Copy Markdown

Typing analysis

Note: Ignored files are excluded from the next sections.

steep:ignore comments

This PR introduces 9 steep:ignore comments.

steep:ignore comments (+9-0)Introduced:
lib/datadog/opentelemetry/logs.rb:45
lib/datadog/opentelemetry/signal_configuration.rb:15
lib/datadog/opentelemetry/signal_configuration.rb:25
lib/datadog/opentelemetry/signal_configuration.rb:26
lib/datadog/opentelemetry/signal_configuration.rb:27
lib/datadog/opentelemetry/signal_configuration.rb:29
lib/datadog/opentelemetry/signal_configuration.rb:31
lib/datadog/opentelemetry/signal_configuration.rb:44
lib/datadog/opentelemetry/signal_configuration.rb:46

Untyped methods

This PR introduces 4 partially typed methods, and clears 2 partially typed methods. It increases the percentage of typed methods from 62.26% to 62.57% (+0.31%).

Partially typed methods (+4-2)Introduced:
sig/datadog/opentelemetry/configuration/settings.rbs:33
└── def headers: () -> ::Hash[untyped, untyped]
sig/datadog/opentelemetry/configuration/settings.rbs:53
└── def headers: () -> ::Hash[untyped, untyped]?
sig/datadog/opentelemetry/configuration/settings.rbs:71
└── def headers: () -> ::Hash[untyped, untyped]?
sig/datadog/opentelemetry/sdk/logs_exporter.rbs:14
└── def initialize: (endpoint: ::String, timeout: ::Float, headers: ::Hash[untyped, untyped]) -> void
Cleared:
sig/datadog/opentelemetry/configuration/settings.rbs:31
└── def headers: () -> ::Hash[untyped, untyped]
sig/datadog/opentelemetry/configuration/settings.rbs:51
└── def headers: () -> ::Hash[untyped, untyped]?

If you believe a method or an attribute is rightfully untyped or partially typed, you can add # untyped:accept on the line before the definition to remove it from the stats.

@mabdinur
mabdinur force-pushed the munir/implement-otel-logs branch from 163ee55 to ab5c738 Compare March 12, 2026 20:38
@datadog-datadog-prod-us1

datadog-datadog-prod-us1 Bot commented Mar 12, 2026

Copy link
Copy Markdown
Contributor

Tests

Fix all issues with BitsAI or with Cursor

⚠️ Warnings

❄️ 21 New flaky tests detected

OpenTelemetry Logs Integration Basic Functionality exports a log record from rspec   View in Datadog   (Fix with Cursor)
undefined method 'force_flush' for an instance of OpenTelemetry::Internal::ProxyLoggerProvider

Failure/Error: provider.force_flush

NoMethodError:
  undefined method 'force_flush' for an instance of OpenTelemetry::Internal::ProxyLoggerProvider
./spec/datadog/opentelemetry/logs_spec.rb:89:in 'block (3 levels) in <top (required)>'
./spec/spec_helper.rb:275:in 'block (2 levels) in <top (required)>'
./spec/spec_helper.rb:155:in 'block (2 levels) in <top (required)>'
/usr/local/bundle/gems/webmock-3.23.1/lib/webmock/rspec.rb:39:in 'block (2 levels) in <top (required)>'
...
OpenTelemetry Logs Integration Configuration configuration priority uses the general OTLP endpoint from rspec   View in Datadog   (Fix with Cursor)
expected: #<Encoding:UTF-8> "http://general:4317/v1/logs"
     got: #<Encoding:US-ASCII> ""

(compared using ==)

Failure/Error: expect(exporter.instance_variable_get(:@uri).to_s).to eq('http://general:4317/v1/logs')

  expected: #<Encoding:UTF-8> "http://general:4317/v1/logs"
       got: #<Encoding:US-ASCII> ""

...
OpenTelemetry Logs Integration Configuration configuration priority uses the general OTLP headers from rspec   View in Datadog   (Fix with Cursor)
undefined method '[]' for nil

Failure/Error: expect(exporter.instance_variable_get(:@headers)['general']).to eq('value')

NoMethodError:
  undefined method '[]' for nil
./spec/datadog/opentelemetry/logs_spec.rb:199:in 'block (4 levels) in <top (required)>'
./spec/spec_helper.rb:275:in 'block (2 levels) in <top (required)>'
./spec/spec_helper.rb:155:in 'block (2 levels) in <top (required)>'
/usr/local/bundle/gems/webmock-3.23.1/lib/webmock/rspec.rb:39:in 'block (2 levels) in <top (required)>'
...
View all

ℹ️ Info

No other issues found (see more)

🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 94.48%
Overall Coverage: 97.14% (-0.03%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a0f68ee | Docs | Datadog PR Page | Give us feedback!

@pr-commenter

pr-commenter Bot commented Mar 12, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-05-14 22:32:32

Comparing candidate commit 30fc0c6 in PR branch munir/implement-otel-logs with baseline commit 421d0e9 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 45 metrics, 1 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

@mabdinur mabdinur added the AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos label Mar 16, 2026
@mabdinur mabdinur changed the title [WIP] feat(otel): add otel logs support feat(otel): add otel logs support May 6, 2026
@mabdinur
mabdinur force-pushed the munir/implement-otel-logs branch from 6d04056 to c8199ac Compare May 8, 2026 15:01
Comment thread lib/datadog/opentelemetry/sdk/id_generator.rb Outdated
@mabdinur
mabdinur marked this pull request as ready for review May 12, 2026 19:39
@mabdinur
mabdinur requested review from a team as code owners May 12, 2026 19:39
@mabdinur
mabdinur requested a review from vpellan May 12, 2026 19:39

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e29c67f104

ℹ️ 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".

Comment thread lib/datadog/opentelemetry/logs.rb Outdated
Comment thread gemfiles/ruby_3.5_opentelemetry.gemfile Outdated
Comment thread lib/datadog/opentelemetry/sdk/configurator.rb Outdated
Comment thread lib/datadog/opentelemetry/sdk/logs_exporter.rb Outdated
Comment thread lib/datadog/opentelemetry/logs.rb Outdated
Comment thread lib/datadog/opentelemetry/logs.rb Outdated
Comment thread sig/datadog/opentelemetry/logs.rbs Outdated
Comment thread sig/datadog/opentelemetry/sdk/logs_exporter.rbs Outdated
Comment thread sig/datadog/opentelemetry/signal_configuration.rbs Outdated
Comment thread Steepfile Outdated
Comment thread spec/datadog/opentelemetry/logs_spec.rb
@mabdinur
mabdinur force-pushed the munir/implement-otel-logs branch from 68e13d6 to 1c319d8 Compare May 13, 2026 14:58
@mabdinur
mabdinur requested a review from vpellan May 13, 2026 14:58
Comment thread lib/datadog/opentelemetry/logs.rb Outdated
Comment thread gemfiles/ruby_3.1_opentelemetry.gemfile.lock Outdated
Comment thread Steepfile Outdated

@vpellan vpellan left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approving so that it's not blocked

@mabdinur
mabdinur requested a review from marcotc May 13, 2026 19:20
Comment thread lib/datadog/opentelemetry/sdk/configurator.rb Outdated
Comment thread lib/datadog/opentelemetry/sdk/configurator.rb Outdated
@mabdinur
mabdinur requested a review from marcotc May 14, 2026 14:21
@mabdinur
mabdinur merged commit 28d0dda into master May 15, 2026
589 checks passed
@mabdinur
mabdinur deleted the munir/implement-otel-logs branch May 15, 2026 14:08
@dd-octo-sts dd-octo-sts Bot added this to the 2.34.0 milestone May 15, 2026
@Strech Strech mentioned this pull request May 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated Largely based on code generated by an AI or LLM. This label is the same across all dd-trace-* repos core Involves Datadog core libraries otel OpenTelemetry-related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants