Skip to content

opentelemetry-exporter-otlp-proto-grpc: tolerate invalid timeout env vars - #5448

Merged
herin049 merged 5 commits into
open-telemetry:mainfrom
Eason09053360:fix-otlp-env-timeout-fallback
Oct 7, 2026
Merged

herin049 merged 5 commits into
open-telemetry:mainfrom
Eason09053360:fix-otlp-env-timeout-fallback

Conversation

@Eason09053360

@Eason09053360 Eason09053360 commented Jul 20, 2026 •

Copy link
Copy Markdown
Member

Description

The OTLP gRPC exporters parse their timeout env vars with a bare float() in __init__, so an invalid value like OTEL_EXPORTER_OTLP_TIMEOUT=10s — or a declared-but-empty variable — raises ValueError during exporter construction and takes down SDK startup.

This adds a _timeout_from_env() helper in opentelemetry-exporter-otlp-proto-grpc that warns and falls back to the default instead, matching how the repo already handles invalid temporality and export-interval values. Applied to the four gRPC call sites (mixin, trace, metric, log); precedence between the signal-specific and generic variables is unchanged.

Scope note: this PR originally covered the HTTP exporters as well. #5389 landed the same warn-and-fall-back behaviour for HTTP while this was open (_resolve_timeout() in otlp/proto/http/_common), so the HTTP half has been dropped and this is now gRPC-only. Deduplicating _resolve_timeout() between otlp-proto-http and otlp-json-http is left for a follow-up.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

How Has This Been Tested?

uv run --with pytest pytest exporter/opentelemetry-exporter-otlp-proto-grpc/tests/ -q     # 76 passed
uv run --with ruff ruff check exporter/opentelemetry-exporter-otlp-proto-grpc            # clean
uv run --with ruff ruff format --check exporter/opentelemetry-exporter-otlp-proto-grpc   # clean

Does This PR Require a Contrib Repo Change?

  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added

@Eason09053360
Eason09053360 marked this pull request as ready for review July 20, 2026 13:11
@Eason09053360
Eason09053360 requested a review from a team as a code owner July 20, 2026 13:11
Comment thread exporter/opentelemetry-exporter-otlp-proto-common/tests/test_timeout_from_env.py Outdated
@Eason09053360
Eason09053360 force-pushed the fix-otlp-env-timeout-fallback branch from 3baee13 to 76c758f Compare July 24, 2026 00:59
@xrmx xrmx moved this to Ready for review in Python PR digest Jul 24, 2026
@Eason09053360
Eason09053360 force-pushed the fix-otlp-env-timeout-fallback branch 2 times, most recently from 173ff7a to d46d1ad Compare August 6, 2026 05:57
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Merged · refreshed 2026-10-07 01:21 UTC

Status above doesn't look right?
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

The gRPC exporters parse their timeout environment variables with a bare
float(), so a value like OTEL_EXPORTER_OTLP_TIMEOUT=10s raises ValueError
during exporter construction and takes down SDK startup.

Add a shared _timeout_from_env() helper in opentelemetry-exporter-otlp-
proto-common that warns and falls back instead, matching how the repo
already handles invalid temporality and export-interval values, and use it
from the gRPC mixin and the three signal exporters. Precedence between the
signal-specific and generic variables is unchanged.

Also fix `timeout or ...` silently discarding an explicit timeout=0; it is
now `timeout is not None`.

The HTTP exporters got the same treatment in open-telemetry#5389, so this change is
limited to the gRPC exporters.
@Eason09053360
Eason09053360 force-pushed the fix-otlp-env-timeout-fallback branch from 969244c to 8cb472c Compare August 26, 2026 05:51
@Eason09053360 Eason09053360 changed the title fix_otlp_timeout_parsing_fallback opentelemetry-exporter-otlp-proto-grpc: fall back to the default when a timeout env var is invalid Aug 26, 2026
@Eason09053360

Copy link
Copy Markdown
Member Author

Rebased onto main and rescoped this PR to the gRPC exporters only.

While this was open, #5389 landed the same warn-and-fall-back behaviour for the HTTP exporters (_resolve_timeout() in otlp/proto/http/_common), including the timeout=0 precedence fix. That made the HTTP half of this PR redundant and was the source of the merge conflicts, so I dropped it. What remains is the gRPC side, which still parses its timeout env vars with a bare float():

grpc/exporter.py

self._timeout = timeout or float(environ.get(OTEL_EXPORTER_OTLP_TIMEOUT, 10))

grpc/{trace,metric,_log}_exporter/init.py

environ_timeout = environ.get(OTEL_EXPORTER_OTLP_TRACES_TIMEOUT)
environ_timeout = float(environ_timeout) if environ_timeout is not None else None
So OTEL_EXPORTER_OTLP_TIMEOUT=10s still raises ValueError during exporter construction, and timeout=0 is still discarded by or.

The shared _timeout_from_env() helper stays in opentelemetry-exporter-otlp-proto-common, since the gRPC exporter depends on that package but not on the newer opentelemetry-exporter-otlp-common.


One follow-up worth doing separately: _resolve_timeout() is now duplicated between otlp-proto-http and otlp-json-http, and neither names the offending environment variable in its warning (the thing @herin049 asked for here). Happy to open a PR unifying those if that sounds useful.

@Eason09053360 Eason09053360 changed the title opentelemetry-exporter-otlp-proto-grpc: fall back to the default when a timeout env var is invalid opentelemetry-exporter-otlp-proto-grpc: tolerate invalid timeout env vars Aug 26, 2026
Only the gRPC exporters use it now that the HTTP side landed in open-telemetry#5389.

It lives in the package __init__ rather than exporter.py because the
logger there has a DuplicateFilter keyed on the message template, which
would drop the warning for a second invalid variable.
Honouring an explicit timeout=0 makes the gRPC exporter set a deadline
that has already passed, so every export fails with DEADLINE_EXCEEDED.
Declarative config passes timeout=0 for "no limit", so that needs its own
change. Keep the existing `timeout or ...` fallback here.
@Eason09053360

Copy link
Copy Markdown
Member Author

I also dropped the timeout=0 change, so the gRPC exporters keep their existing timeout or ... fallback.

If an explicit timeout=0 is honoured, the gRPC exporter sets a deadline that has already passed, and every export fails with DEADLINE_EXCEEDED. Declarative config also passes timeout: 0 to mean "no limit".
My perspective both need a separate change, so this PR is back to only tolerating invalid timeout env vars.

Copilot AI 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.

Copilot review overview

🟢 Approval recommended

The focused changes preserve timeout precedence, include regression coverage, and have no identified blocking issues.

Review effort: Balanced
Findings: None

What changed in this PR

Makes OTLP gRPC exporter startup tolerate malformed timeout environment variables, complementing the HTTP handling delivered in #5389.

Changes:

  • Adds shared timeout parsing with warnings and fallback behavior.
  • Applies it to the mixin and trace, metric, and log exporters while preserving precedence.
  • Adds regression tests and a changelog entry.
File Description
exporter/​opentelemetry-exporter-otlp-proto-grpc/​tests/​test_timeout_from_env.py Tests parsing, fallback, precedence, and warnings.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​tests/​test_otlp_trace_exporter.py Tests invalid trace timeout handling.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​tests/​test_otlp_exporter_mixin.py Tests generic timeout fallback.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​src/​opentelemetry/​exporter/​otlp/​proto/​grpc/​trace_exporter/​__init__.py Uses shared parsing for traces.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​src/​opentelemetry/​exporter/​otlp/​proto/​grpc/​metric_exporter/​__init__.py Uses shared parsing for metrics.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​src/​opentelemetry/​exporter/​otlp/​proto/​grpc/​exporter.py Uses shared parsing for the generic timeout.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​src/​opentelemetry/​exporter/​otlp/​proto/​grpc/​_log_exporter/​__init__.py Uses shared parsing for logs.
exporter/​opentelemetry-exporter-otlp-proto-grpc/​src/​opentelemetry/​exporter/​otlp/​proto/​grpc/​__init__.py Defines the timeout parsing helper.
.changelog/​5448.fixed Documents the fix.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@herin049
herin049 enabled auto-merge October 7, 2026 01:06
@herin049
herin049 added this pull request to the merge queue Oct 7, 2026
Merged via the queue into open-telemetry:main with commit f36c128 Oct 7, 2026
579 checks passed
herin049 pushed a commit to RichardoMrMu/opentelemetry-python that referenced this pull request Oct 12, 2026
…ar (open-telemetry#5705)

* fix(prometheus): tolerate invalid OTEL_EXPORTER_PROMETHEUS_PORT env var

_AutoPrometheusMetricReader parsed OTEL_EXPORTER_PROMETHEUS_PORT with a
bare int() in __init__, so a non-integer value (e.g. "9464abc") or an
empty string raised ValueError while building the auto-configured reader
and took opentelemetry-instrument/SDK startup down. This is the same class
of startup crash already fixed for the OTLP exporters (HTTP _resolve_timeout
in open-telemetry#5389, gRPC _timeout_from_env in open-telemetry#5448) and the Zipkin exporters (open-telemetry#5704).

Add a private _port_from_env() that skips unset/empty values silently, logs
a warning for non-integer values, and falls back to the 9464 default.
Explicit configuration is unaffected (the reader's auto server only reads
the env var).

Assisted-by: Doubao

* changelog: add fragment for PR open-telemetry#5705

* test(prometheus): ruff-format the new entrypoint timeout tests

The `misc / precommit` job failed because the two added test signatures were split across lines while ruff (v0.16.0, line-length 120) keeps them on one line. Run `ruff format` so `pre-commit run ruff-format` is clean.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

6 participants