Skip to content

feat(profiling): add GC observability collector - #19940

Draft
vlad-scherbich wants to merge 7 commits into
vlad/runtime-gc-metricsfrom
vlad/profiling-gc-collector
Draft

feat(profiling): add GC observability collector#19940
vlad-scherbich wants to merge 7 commits into
vlad/runtime-gc-metricsfrom
vlad/profiling-gc-collector

Conversation

@vlad-scherbich

Copy link
Copy Markdown
Contributor

Adds GCCollector that hooks gc.callbacks to measure per-generation pause durations, emits alloc samples for collected objects, and records explicit gc.collect() call counts per flush interval. Controlled via DD_PROFILING_GC_ENABLED (default: true).

Description

Testing

Risks

Additional Notes

Adds GCCollector that hooks gc.callbacks to measure per-generation pause
durations, emits alloc samples for collected objects, and records explicit
gc.collect() call counts per flush interval. Controlled via
DD_PROFILING_GC_ENABLED (default: true).
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Pipelines  Tests

Unblock PR with BitsAI

⚠️ Warnings

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 6 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-py | build linux serverless: [amd64, cp315-cp315, v113741238-d2b8243-manylinux2014_x86_64, 1] — 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

DataDog/apm-reliability/dd-trace-py | build linux serverless: [arm64, cp315-cp315, v113741357-d2b8243-manylinux2014_aarch64, 1] — 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

DataDog/apm-reliability/dd-trace-py | build linux: [amd64, cp315-cp315, v113741238-d2b8243-manylinux2014_x86_64] — 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

View all 6 failed jobs.

❄️ 2 New flaky tests detected

test_snapshot_emits_config_sample[py3.10] from test_gc.py
module 'ddtrace.profiling.collector' has no attribute 'gc'
test_snapshot_emits_config_sample[py3.9] from test_gc.py
module 'ddtrace.profiling.collector' has no attribute 'gc'

View in Flaky Test Management

ℹ️ Info

No other issues found (see more)

🧪 All tests passed

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: a57f396 | Docs | View more details | Give us feedback!

@vlad-scherbich
vlad-scherbich requested a lite review from Copilot August 28, 2026 20:18
@vlad-scherbich

Copy link
Copy Markdown
Contributor Author

@codex review

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 28, 2026

Copy link
Copy Markdown

Codeowners resolved as

Resolved from the full PR diff against vlad/runtime-gc-metrics using the target branch CODEOWNERS file.
CODEOWNERS team requests not listed below are not required by the current file set.

ddtrace/internal/settings/_supported_configurations.py                  @DataDog/apm-python
ddtrace/internal/settings/profiling.py                                  @DataDog/profiling-python
ddtrace/internal/settings/profiling.pyi                                 @DataDog/profiling-python
ddtrace/profiling/collector/gc.py                                       @DataDog/profiling-python
ddtrace/profiling/profiler.py                                           @DataDog/profiling-python
releasenotes/notes/profiling-gc-collector-7a3c1e9b2d4f.yaml             @DataDog/apm-python
supported-configurations.json                                           @DataDog/apm-python
tests/profiling/collector/test_gc.py                                    @DataDog/profiling-python
tests/profiling/test_profiler.py                                        @DataDog/profiling-python
tests/profiling/test_profiling_config.py                                @DataDog/profiling-python

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 28, 2026

Copy link
Copy Markdown

Circular import analysis

⚠️ Existing circular imports

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

ddtrace.llmobs -> ddtrace.llmobs._evaluators -> ddtrace.llmobs._evaluators.format -> ddtrace.llmobs._experiment -> ddtrace.llmobs
ddtrace.errortracking._handled_exceptions.bytecode_injector -> ddtrace.errortracking._handled_exceptions.callbacks -> ddtrace.errortracking._handled_exceptions.collector -> ddtrace.errortracking._handled_exceptions.bytecode_reporting -> ddtrace.errortracking._handled_exceptions.bytecode_injector
ddtrace.appsec._asm_request_context -> ddtrace.appsec._iast._iast_request_context_base -> ddtrace.appsec._iast._iast_env -> ddtrace.appsec._iast.reporter -> ddtrace.appsec._exploit_prevention.stack_traces -> ddtrace.appsec._asm_request_context

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Aug 28, 2026

Copy link
Copy Markdown

Dependency direction analysis

⚠️ Existing dependency direction violations

There are 240 dependency direction violations that already exist on the base branch and have not been changed by this PR.

Show existing violations (showing 5 of 240 highest severity)
ddtrace.internal.tracemethods -×-> ddtrace.trace  (internal-core -> product:tracing, score=135)
ddtrace.llmobs._integrations.anthropic -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=133)
ddtrace.llmobs._integrations.pydantic_ai -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=133)
ddtrace.llmobs._integrations.claude_agent_sdk -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=133)
ddtrace.llmobs._integrations.base -×-> ddtrace.trace  (product:llmobs -> product:tracing, score=133)

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

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

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.

Pull request overview

Adds a new profiling “GC observability” collector that hooks gc.callbacks to emit profiling samples around GC pauses, plus a new configuration flag (DD_PROFILING_GC_ENABLED) to control enablement, and wires the collector into the main Profiler.

Changes:

  • Introduces GCCollector that patches gc.collect, subscribes to gc.callbacks, emits wall-time samples for GC pauses, and emits a periodic “gc.config” snapshot sample.
  • Adds DD_PROFILING_GC_ENABLED to profiling settings and supported configuration registry, and enables the collector in ddtrace.profiling.profiler.Profiler.
  • Adds unit + integration tests validating callback lifecycle and that GC samples appear in exported profiles.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/profiling/collector/test_gc.py New unit/integration tests for GCCollector behavior and emitted samples.
supported-configurations.json Registers new DD_PROFILING_GC_ENABLED configuration key.
ddtrace/profiling/profiler.py Wires GCCollector into the profiler collector initialization flow.
ddtrace/profiling/collector/gc.py New collector implementation using gc.callbacks + ddup.SampleHandle.
ddtrace/internal/settings/profiling.py Adds ProfilingConfigGC (profiling_config.gc.enabled).
ddtrace/internal/settings/_supported_configurations.py Updates generated allowlist to include DD_PROFILING_GC_ENABLED.
Suppressed comments (1)

ddtrace/profiling/collector/gc.py:79

  • push_alloc(size, count) treats the first argument as alloc-space (bytes) and the second as alloc-samples. Passing the number of collected objects as the size and a constant count of 1 will misrepresent the data in the allocation profile (object count will appear as bytes).
            collected = info.get("collected", 0)
            if collected > 0:
                handle2 = ddup.SampleHandle()
                handle2.push_alloc(collected, 1)
                handle2.push_frame(frame_name, "gc", 0, gen)
                handle2.push_monotonic_ns(time.monotonic_ns())
                handle2.flush_sample()

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

Comment thread tests/profiling/collector/test_gc.py Outdated
Comment thread ddtrace/profiling/profiler.py
Comment thread supported-configurations.json
Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/internal/settings/profiling.py

@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: 5fff59f9fc

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/profiling/collector/gc.py
Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/profiling/collector/gc.py Outdated
Comment thread ddtrace/internal/settings/profiling.py Outdated
…ngs reload

Config-sample uniqueness raced with gc.callbacks walltime, and importlib.reload
replaced ProfilingConfigHeap so later isinstance() checks failed.
Restore gc.collect only when our wrapper is still installed, drain the
explicit-call counter under a lock, and reset in-flight state after fork.
Align help/docstrings with emitted samples and add a release note.
Keep the new GC pause collector off until customers set
DD_PROFILING_GC_ENABLED=true.

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.

Pull request overview

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Comment on lines +2880 to +2884
{
"implementation": "C",
"type": "boolean",
"default": "true"
}
Comment on lines +94 to +95
# TODO: If we later want collected-object counts on the profile, add a
# dedicated libdatadog/pprof sample type. Do not reuse push_alloc.
Comment on lines +88 to +92
handle: ddup.SampleHandle = ddup.SampleHandle()
handle.push_walltime(pause_ns, 1)
handle.push_frame(frame_name, "gc", 0, gen)
handle.push_monotonic_ns(time.monotonic_ns())
handle.flush_sample()
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.

2 participants