Skip to content

fix(telemetry): avoid startup import races#19014

Closed
florentinl wants to merge 5 commits into
mainfrom
agent/fix-telemetry-asm-import-race
Closed

fix(telemetry): avoid startup import races#19014
florentinl wants to merge 5 commits into
mainfrom
agent/fix-telemetry-asm-import-race

Conversation

@florentinl

@florentinl florentinl commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Description

Prevents the instrumentation telemetry worker from initiating imports while ddtrace is still initializing.

The telemetry writer starts during package import. With a short heartbeat interval, its background thread could concurrently import either:

  • ASM settings while reporting discovered HTTP endpoints
  • Global tracer configuration while collecting dependencies and SCA metadata

Both paths could expose partially initialized modules and fail startup with a circular-import ImportError. Endpoint reporting and dependency collection now use settings only after their modules are fully initialized; otherwise, telemetry defers that work to a later heartbeat. Dependency collection defers before scanning modules so no dependency state is lost.

This adds a subprocess stress regression covering dependency collection both enabled and disabled, direct dependency-tracker coverage, and a release note.

Testing

Regression tests

Risks

Low. Endpoint reporting or dependency collection can be deferred by one telemetry heartbeat if the required settings are still initializing. Endpoint and dependency state remain queued for the next collection cycle.

Additional Notes

Original failure: https://github.com/DataDog/dd-trace-py/actions/runs/29244084795/job/86802866160#step:7:12111

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codeowners resolved as

ddtrace/internal/telemetry/dependency_tracker.py                        @DataDog/apm-python
releasenotes/notes/telemetry-worker-import-races-5be8c9d93f3a7261.yaml  @DataDog/apm-python
tests/telemetry/test_dependency.py                                      @DataDog/apm-python
tests/telemetry/test_telemetry.py                                       @DataDog/apm-python

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jul 13, 2026

Copy link
Copy Markdown

Circular import analysis

⚠️ Existing circular imports

There are 2516 circular imports that already exist on the base branch and have not been changed by this PR.

Show existing cycles (showing 5 of 2516 shortest)
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.botocore -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.kafka -> ddtrace.internal.datastreams
ddtrace.internal.core -> ddtrace._trace.span -> ddtrace.internal.core
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.kombu -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.google_cloud_pubsub -> ddtrace.internal.datastreams

To see all cycles, download the cycles-base.json and cycles-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/cycles.py compare cycles-base.json cycles-pr.json

✅ Circular imports removed

8 circular import(s) have been removed by this PR.

Show removed cycles (showing 5 of 8 shortest)
ddtrace.internal.telemetry -> ddtrace.internal.telemetry.writer -> ddtrace.internal.settings.asm -> ddtrace.internal.settings._config -> ddtrace.internal.telemetry
ddtrace.internal.telemetry -> ddtrace.internal.telemetry.writer -> ddtrace.internal.telemetry.dependency_tracker -> ddtrace.internal.settings._config -> ddtrace.internal.telemetry
ddtrace.internal.telemetry -> ddtrace.internal.telemetry.writer -> ddtrace.internal.settings.asm -> ddtrace.internal.settings._config -> ddtrace.internal.settings.endpoint_config -> ddtrace.internal.utils.http -> ddtrace.internal.utils -> ddtrace.internal.core -> ddtrace._trace.span -> ddtrace._trace._span_pointer -> ddtrace._trace.telemetry -> ddtrace.internal.telemetry
ddtrace.internal.telemetry -> ddtrace.internal.telemetry.writer -> ddtrace.internal.telemetry.dependency_tracker -> ddtrace.internal.settings._config -> ddtrace.internal.settings.http -> ddtrace.internal.utils.http -> ddtrace.internal.utils -> ddtrace.internal.core -> ddtrace._trace.span -> ddtrace._trace._span_pointer -> ddtrace._trace.telemetry -> ddtrace.internal.telemetry
ddtrace.internal.telemetry -> ddtrace.internal.telemetry.writer -> ddtrace.internal.telemetry.dependency_tracker -> ddtrace.internal.settings._config -> ddtrace.internal.settings.endpoint_config -> ddtrace.internal.utils.http -> ddtrace.internal.utils -> ddtrace.internal.core -> ddtrace._trace.span -> ddtrace._trace._span_pointer -> ddtrace._trace.telemetry -> ddtrace.internal.telemetry

To see all cycles, download the cycles-base.json and cycles-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/cycles.py compare cycles-base.json cycles-pr.json

@datadog-datadog-us1-prod

This comment has been minimized.

@florentinl
florentinl force-pushed the agent/fix-telemetry-asm-import-race branch from b433168 to 759db1a Compare July 13, 2026 15:25
@florentinl florentinl changed the title fix(asm): avoid telemetry import race fix(telemetry): avoid startup import races Jul 13, 2026
@florentinl florentinl closed this Jul 16, 2026
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