fix(tracing): stop FastAPI 0.142 auto-exporting; bump fastapi to 0.142.2 by TadMSTR · Pull Request #37 · TadMSTR/webhook-doorman · GitHub
Skip to content

fix(tracing): stop FastAPI 0.142 auto-exporting; bump fastapi to 0.142.2 - #37

Merged
TadMSTR merged 1 commit into
mainfrom
fix/fastapi-0142-otel-autoconfig
Oct 7, 2026
Merged

TadMSTR merged 1 commit into
mainfrom
fix/fastapi-0142-otel-autoconfig

Conversation

@TadMSTR

@TadMSTR TadMSTR commented Oct 7, 2026

Copy link
Copy Markdown
Owner

Supersedes #31. Taking #31 as-is would double every exported span in production. The deployed container has OTEL_EXPORTER_OTLP_ENDPOINT set.

The defect

FastAPI 0.142.0 added native OpenTelemetry (fastapi/fastapi#16403). On lifespan startup, fastapi.telemetry._runtime._configure_from_environment reads OTEL_EXPORTER_OTLP_ENDPOINT. That's the same variable tracing.py uses as its switch. FastAPI then:

  • attaches its own BatchSpanProcessor(OTLPSpanExporter) to the TracerProvider that is already installed. Its docstring says it "does not inspect or deduplicate other components' exporters".
  • installs SDK MeterProvider and LoggerProvider with OTLP exporters.

#31's CI was green because no test looks at exporter count.

Measured

I ran create_app with tracing on against a local OTLP capture server, made 5 requests and flushed:

FastAPI span processors (before → after lifespan) meter / logger provider OTLP POSTs
0.141.1 1 → 1 proxy / proxy /v1/traces ×1
0.142.2 1 → 2 SDK / SDK /v1/traces ×2, /v1/metrics ×2
0.142.2 + this PR 1 → 1 proxy / proxy /v1/traces ×1

Fix

FastAPI(..., telemetry={"auto_configure": False}). Before 0.142 the keyword lands in app.extra and does nothing, so the declared fastapi>=0.115,<1 range stays. I checked this on 0.141.1. Native request spans are already suppressed, because FastAPI detects the contrib FastAPIInstrumentor. Duplicate export is the only problem.

Test

TestFastAPIDoesNotExportOnItsOwn sets the endpoint in the real environment, which is what both create_app and FastAPI read, and runs lifespan. It then asserts exactly one span processor and no SDK meter or logger provider. It resets OTel's one-shot globals and FastAPI's _configured registry, so the test can't pass vacuously against an earlier test's provider.

  • With the fix removed (mutant): fails at the span-processor assertion.
  • On FastAPI 0.141.1: skipped, with the reason "FastAPI < 0.142 has no native telemetry". 669 passed.
  • On 0.142.2 (lock): 670 passed. ruff check and format are clean.

Lock

fastapi 0.141.1 → 0.142.2. opentelemetry-api becomes a base dependency of fastapi. That's the API only, with no SDK or exporter.

Refs vikunja#746 (0.x minor treated as a major), vikunja#1031.

🤖 Generated with Claude Code

FastAPI 0.142's native telemetry reads OTEL_EXPORTER_OTLP_ENDPOINT at lifespan
startup and attaches its own OTLP exporter to the installed TracerProvider, plus
SDK meter/logger providers. With tracing on, every span was exported twice and
a metrics stream appeared (measured against a local OTLP capture: 1 -> 2 span
processors, /v1/metrics POSTs). create_app now passes
telemetry={"auto_configure": False}; inert before 0.142 (lands in app.extra).

Regression test asserts one span processor and no SDK meter/logger provider
after lifespan; it fails with the fix removed and skips on FastAPI < 0.142.
Supersedes Dependabot #31.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer
@TadMSTR
TadMSTR merged commit 8d935a0 into main Oct 7, 2026
10 checks passed
@TadMSTR
TadMSTR deleted the fix/fastapi-0142-otel-autoconfig branch October 7, 2026 00:41
TadMSTR pushed a commit that referenced this pull request Oct 7, 2026
Resolves the CHANGELOG [Unreleased] conflict: one section, Fixed / Added /
Changed / Known.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer
TadMSTR pushed a commit that referenced this pull request Oct 7, 2026
Records #37's squash (8d935a0) as a parent. The previous commit carried the
same tree but only one parent, so GitHub saw the branch as conflicting.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TadMSTR added a commit that referenced this pull request Oct 7, 2026
#36)

* chore(image): python 3.14-slim, with a 3.14 test leg and a parity gate

Supersedes Dependabot #7. Pins both stages to today's multi-arch 3.14-slim
index instead of #7's 2026-09-07 digest, adds 3.14 to the CI matrix, and adds
a CI job that fails when the Dockerfile's Python is not a matrix entry, so a
base-image bump cannot land without a test leg for it (vikunja#729).

669 tests pass on 3.14.8; verify-image.sh passes on the built image. Trivy:
the 8 fixable OS findings in the published 0.5.1 image are gone; pip's
vendored msgpack/setuptools/urllib3 are unchanged (identical on 3.13).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer

* Merge origin/main (#37) into chore/python-3.14-image

Resolves the CHANGELOG [Unreleased] conflict: one section, Fixed / Added /
Changed / Known.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer

---------

Co-authored-by: developer-agent <developer@forge>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@TadMSTR

TadMSTR commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
⚠️ Action not completed

Pull request is closed.

@TadMSTR

TadMSTR commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

forge agent report — composed by the security agent (model claude-sonnet-5) for build dependabot-sweep-2026-10-p4-deferred-majors.
Posted through a shared automation account, so the author of this post is not a per-agent identity.
Full report, internal: host-forge/build-reports/dependabot-sweep-2026-10-p4-deferred-majors/audit.md

CodeRabbit round 1 could not be read; the audit proceeds without it. Security audit started.

Scope Count
Repositories 3
Files in scope 14

Findings will be posted here when the audit completes.

@TadMSTR

TadMSTR commented Oct 7, 2026

Copy link
Copy Markdown
Owner Author

forge agent report — composed by the security agent (model claude-sonnet-5) for build dependabot-sweep-2026-10-p4-deferred-majors.
Posted through a shared automation account, so the author of this post is not a per-agent identity.
Full report, internal: host-forge/build-reports/dependabot-sweep-2026-10-p4-deferred-majors/audit.md

Security audit complete (round 1) — 2 findings.

Severity Count
Critical 0
High 0
Medium 0
Low 0
Info 2
Disposition Count
Resolved 0
Accepted 0
Deferred 0

Categories: ci-config, dependency

Finding detail is in the internal report referenced above.

@TadMSTR TadMSTR mentioned this pull request Oct 7, 2026
TadMSTR added a commit that referenced this pull request Oct 7, 2026
* chore(release): 0.6.0

Python 3.14 image (#36) and the FastAPI 0.142 telemetry auto-configure fix
(#37). Redeploying clears the 0.5.1 image's OS findings (vikunja#1033).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer

* docs(changelog): add the 0.6.0 release link

test_the_declared_version_is_the_same_number_everywhere requires it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

agent-id: developer

---------

Co-authored-by: developer-agent <developer@forge>
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.

1 participant