Repository navigation
fix(zipkin): tolerate invalid OTEL_EXPORTER_ZIPKIN_TIMEOUT env var - #5704
Open
RichardoMrMu wants to merge 7 commits into
Open
RichardoMrMu wants to merge 7 commits into
RichardoMrMu wants to merge 7 commits into
Conversation
Both Zipkin exporters parsed OTEL_EXPORTER_ZIPKIN_TIMEOUT with a bare int() in __init__, so an invalid value (e.g. "10s") raised ValueError during exporter construction and took SDK startup down, unlike the OTLP HTTP/gRPC exporters which warn and fall back to the default. Add _timeout_from_env() in each exporter that skips unset/empty values silently, logs a warning for non-integer values, and falls back to the 10 second default. Explicit timeout argument precedence is unchanged. Assisted-by: Doubao
Pull request dashboard statusWaiting on the author · refreshed 2026-10-08 15:50 UTC Respond to 1 review item (e.g. link a commit, explain why not, ask a follow-up):
Status above doesn't look right?
|
1 task done
…/zipkin-timeout-env-fallback (sync to cee5f52)
Restore the original public assignment expression for ZipkinExporter.timeout and wrap it in try/except ValueError so a malformed env var logs a warning and falls back to the default instead of breaking SDK startup.
lzchen
approved these changes
Oct 1, 2026
herin049
approved these changes
Oct 1, 2026
Contributor
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Empty and whitespace-only values incorrectly emit warnings, and tests do not verify silent fallback.
Review effort: Balanced
Findings: 4
Open (4)
What changed in this PR
Adds resilient Zipkin timeout environment parsing to prevent malformed values from breaking SDK startup.
Changes:
- Falls back to the default timeout for invalid values.
- Adds warning and fallback tests.
- Adds a changelog entry.
| File | Description |
|---|---|
.changelog/5704.fixed |
Documents the fix. |
exporter/opentelemetry-exporter-zipkin-json/src/opentelemetry/exporter/zipkin/json/__init__.py |
Adds timeout fallback handling. |
exporter/opentelemetry-exporter-zipkin-json/tests/test_zipkin_exporter.py |
Tests invalid and empty values. |
exporter/opentelemetry-exporter-zipkin-proto-http/src/opentelemetry/exporter/zipkin/proto/http/__init__.py |
Adds timeout fallback handling. |
exporter/opentelemetry-exporter-zipkin-proto-http/tests/test_zipkin_exporter.py |
Tests invalid and empty values. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+132
to
+142
| # A malformed OTEL_EXPORTER_ZIPKIN_TIMEOUT must not break SDK startup. | ||
| try: | ||
| self.timeout = timeout or int(environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT, 10)) | ||
| except ValueError: | ||
| logger.warning( | ||
| "Invalid value %r for %s, using default of %s seconds", | ||
| environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT), | ||
| OTEL_EXPORTER_ZIPKIN_TIMEOUT, | ||
| _DEFAULT_TIMEOUT, | ||
| ) | ||
| self.timeout = _DEFAULT_TIMEOUT |
Comment on lines
+79
to
+83
| os.environ[OTEL_EXPORTER_ZIPKIN_TIMEOUT] = "" | ||
|
|
||
| exporter = ZipkinExporter() | ||
|
|
||
| self.assertEqual(exporter.timeout, 10) |
Comment on lines
+125
to
+135
| # A malformed OTEL_EXPORTER_ZIPKIN_TIMEOUT must not break SDK startup. | ||
| try: | ||
| self.timeout = timeout or int(environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT, 10)) | ||
| except ValueError: | ||
| logger.warning( | ||
| "Invalid value %r for %s, using default of %s seconds", | ||
| environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT), | ||
| OTEL_EXPORTER_ZIPKIN_TIMEOUT, | ||
| _DEFAULT_TIMEOUT, | ||
| ) | ||
| self.timeout = _DEFAULT_TIMEOUT |
Comment on lines
+81
to
+85
| os.environ[OTEL_EXPORTER_ZIPKIN_TIMEOUT] = "" | ||
|
|
||
| exporter = ZipkinExporter() | ||
|
|
||
| self.assertEqual(exporter.timeout, 10) |
Handle unset and whitespace-only timeout values before integer conversion in both Zipkin exporters. Preserve explicit timeout precedence and existing numeric parsing semantics. Add regressions for silent defaults, warning count, valid values and constructor truthiness. Assisted-by: OpenAI Codex Signed-off-by: RichardoMrMu <947676438@qq.com>
…c-symbols check griffe public-symbols-check compares the AST of instance attribute assignments against main. Route the blank-timeout fallback through a local variable instead of changing the self.timeout RHS, so the exported attribute source text stays byte-identical to main. Behavior unchanged: blank/invalid env falls back to _timeout_from_env() (default 10s), explicit timeout wins.
| self.session = session or requests.Session() | ||
| self.session.headers.update({"Content-Type": self.encoder.content_type()}) | ||
| self._closed = False | ||
| timeout = timeout or _timeout_from_env() |
Contributor
There was a problem hiding this comment.
Why are you calling two times environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT ? One here (line below) and one from timeout_from_env()?
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Description
Both Zipkin span exporters construct their timeout with a bare
int(environ.get(OTEL_EXPORTER_ZIPKIN_TIMEOUT, 10))in__init__(opentelemetry-exporter-zipkin-jsonandopentelemetry-exporter-zipkin-proto-http). A malformed value such asOTEL_EXPORTER_ZIPKIN_TIMEOUT=10sraisesValueError: invalid literal for int()while the exporter is being built, which takes SDK/TracerProviderstartup down before any telemetry can flow.The OTLP exporters already tolerate this: the HTTP transport has
_resolve_timeout()(#5389) and the gRPC transport now has_timeout_from_env()(#5448), both of which log a warning and fall back to the default. The Zipkin exporters were the remaining outlier parsing this env var with an unguarded conversion.This change adds a private
_timeout_from_env()in each Zipkin exporter that:10seconds) silently when the variable is unset or empty/whitespace;Precedence of an explicit
timeout=constructor argument is unchanged (timeout or _timeout_from_env()).Type of change
How Has This Been Tested?
Pure-Python, no collector or network needed. Added two tests to each exporter's
test_zipkin_exporter.py:test_constructor_invalid_timeout_env_var_falls_back: setsOTEL_EXPORTER_ZIPKIN_TIMEOUT=10s, asserts the exporter builds withtimeout == 10and emits a WARNING.test_constructor_empty_timeout_env_var_falls_back: sets the variable to"", assertstimeout == 10.Red (before the fix), run per package:
Green (after the fix):
The pre-existing constructor/env/export tests in both files continue to pass, including
test_constructor_all_params_and_env_vars(explicittimeout=precedence) andtest_constructor_env_vars(valid numeric env value).Verification boundary: logic-level unit tests only (constructor configuration); no export round-trip against a live Zipkin instance was exercised, consistent with the existing tests in these modules which mock
requests.Session.post.