Skip to content

feat(tracer): align C span code with v1-compatible stub API (v2 groundwork)#4046

Draft
Leiyks wants to merge 3 commits into
masterfrom
leiyks/dd-trace-php-v2
Draft

feat(tracer): align C span code with v1-compatible stub API (v2 groundwork)#4046
Leiyks wants to merge 3 commits into
masterfrom
leiyks/dd-trace-php-v2

Conversation

@Leiyks

@Leiyks Leiyks commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

What & why

Part of APMLP-1197 (dd-trace-php v1/v2 roadmap). The v1-compatible span
stub API (tracer/ddtrace.stub.php) landed earlier on this branch; this
brings the tracer C code into consistency with it. The v04 wire
format is intentionally kept byte-identical — libdatadog's v1 span
FFI is not yet available, so no wire/protocol switch happens here.

Changes

  • arginfo + struct offsets: regenerated ddtrace_arginfo.h; reordered
    ddtrace_span_properties / ddtrace_root_span_data / ddtrace_span_stack in
    span.h to match the new stub property order (offset parity is
    ABI-critical — a mismatch is silent data corruption).
  • SpanEvent/SpanLink: dropped JsonSerializable + jsonSerialize();
    relocated the serialization into serializer.c → _dd.span_links / events
    meta blobs are byte-identical.
  • component/spanKind: now sourced from the new SpanData properties and
    translated back to meta (component / span.kind) at serialize time, so
    the wire is unchanged; new SpanKind class registered.
  • Dead code: removed stub-removed functions + DD_TRACE_WARN_LEGACY_DD_TRACE;
    finished the userland integration-analytics removal (Integration.php +
    call sites); deleted orphaned tests and rewrote dd_trace_reset helper
    tests without weakening coverage.

Deliberate scope decisions

  • Wire stays v04 (no native ddog_span_new_link/event switch) — deferred
    until libdatadog v1 FFI is ready.
  • New properties attributes / samplingMechanism / hostname get struct
    slots (to keep offsets correct) but are left unwired for now.
  • ddtrace_arginfo.h keeps deprecations doc-only (hand-stripped the
    ZEND_ACC_DEPRECATED flags current gen_stub now emits) to match the
    committed convention and avoid runtime E_DEPRECATED on hot paths;
    reconciling gen_stub output is a separate follow-up.

Testing

Container build clean; 22 span-shape + 26 curl integration + 30
ConfigurationTest tests passing; links/events wire proven byte-identical.

Draft: pending full CI.

Leiyks added 3 commits July 16, 2026 14:08
Signed-off-by: Alexandre Rulleau <alexandre.rulleau@datadoghq.com>
Signed-off-by: Alexandre Rulleau <alexandre.rulleau@datadoghq.com>
Bring the tracer C code into consistency with the already-rewritten
v1-compatible span stub (tracer/ddtrace.stub.php), keeping the v04 wire
format byte-identical (libdatadog v1 FFI is not yet available).

- Regenerate ddtrace_arginfo.h from the stub; reorder the
  ddtrace_span_properties / ddtrace_root_span_data / ddtrace_span_stack
  structs to match the new property declaration order (PHP property
  offsets are bound to these C struct fields).
- Drop SpanEvent/SpanLink JsonSerializable + jsonSerialize(); relocate
  that logic into serializer.c so the _dd.span_links / events meta blobs
  are produced with identical bytes.
- Make component/spanKind sourced from the new SpanData properties,
  translated back into meta (span.kind/component) at serialize time so
  the v04 wire is unchanged. Register the new SpanKind class.
- Remove dead code for stub-removed functions and the
  DD_TRACE_WARN_LEGACY_DD_TRACE config key; complete the userland
  integration-analytics removal (Integration.php + call sites); delete
  tests orphaned by removed functions and rewrite the dd_trace_reset
  helper tests without gutting their coverage.

Refs APMLP-1197.
@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 17, 2026

Copy link
Copy Markdown

Pipelines  Tests

Unblock PR with BitsAI

⚠️ Warnings

🚦 299 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-php | ASAN test_c: [8.0, arm64]   View in Datadog   GitLab

🧪 2 Tests failed

tmp/build_extension/tests/ext/active_span.phpt (DDTrace\active_span basic functionality) from PHP.tmp.build_extension.tests.ext   View in Datadog
Hello, Datadog.
     greet tracer.
     bool(true)
004&#43; object(DDTrace\RootSpanData)#4 (30) {
004- object(DDTrace\RootSpanData)#%d (29) {
       [&#34;name&#34;]=&gt;
       string(15) &#34;active_span.php&#34;
       [&#34;resource&#34;]=&gt;
--
       [&#34;attributes&#34;]=&gt;
...
tmp/build_extension/tests/ext/sandbox/span_clone.phpt (Clone DDTrace\SpanData) from PHP.tmp.build_extension.tests.ext.sandbox   View in Datadog
001&#43; object(DDTrace\RootSpanData)#5 (30) {
001- object(DDTrace\RootSpanData)#%d (29) {
       [&#34;name&#34;]=&gt;
       string(3) &#34;foo&#34;
       [&#34;resource&#34;]=&gt;
--
       [&#34;attributes&#34;]=&gt;
       array(0) {
       }%r(\s*\[&#34;origin&#34;\]=&gt;\s&#43;uninitialized\(string\))?%r
079-   [&#34;propagatedTags&#34;]=&gt;
...

DataDog/apm-reliability/dd-trace-php | test_integrations_pdo: [7.2]   View in Datadog   GitLab

🧪 3 Tests failed

testCustomPDOPrepareWithStringableStatement from tests/Integrations/PDO.DDTrace\Tests\Integrations\PDO\PDOTest   View in Datadog
DDTrace\Tests\Integrations\PDO\PDOTest::testCustomPDOPrepareWithStringableStatement
PDOStatement.execute: Wrong value for &#39;metrics&#39; Array
(
    [trace_id] =&gt; 16233467937087668420
    [span_id] =&gt; 16233467937087668420
    [start] =&gt; 1784293489158071413
    [duration] =&gt; 271625
    [name] =&gt; PDOStatement.execute
    [resource] =&gt; SELECT * FROM tests WHERE id = ?
    [service] =&gt; pdo
...
testDirectQueryHasNoParentIssues from tests/Integrations/PDO.DDTrace\Tests\Integrations\PDO\PDOTest   View in Datadog
DDTrace\Tests\Integrations\PDO\PDOTest::testDirectQueryHasNoParentIssues
PDO.query: Wrong value for &#39;metrics&#39; Array
(
    [trace_id] =&gt; 3098899899622095391
    [span_id] =&gt; 3098899899622095391
    [start] =&gt; 1784293490346679892
    [duration] =&gt; 404251
    [name] =&gt; PDO.query
    [resource] =&gt; SELECT * FROM tests WHERE id=1
    [service] =&gt; pdo
...
View all failed tests

DataDog/apm-reliability/dd-trace-php | test_web_laravel_42: [7.2, cli-server]   View in Datadog   GitLab

🧪 1 Test failed

testScenario from tests/Integrations/Laravel/V4.DDTrace\Tests\Integrations\Laravel\V4\TraceSearchConfigTest   View in Datadog
DDTrace\Tests\Integrations\Laravel\V4\TraceSearchConfigTest::testScenario
laravel.request: Wrong value for &#39;metrics&#39; Array
(
    [service] =&gt; laravel
    [name] =&gt; laravel.request
    [resource] =&gt; HomeController@simple simple_route
    [type] =&gt; web
    [trace_id] =&gt; 11199041820998981060
    [span_id] =&gt; 9654855790133380617
    [parent_id] =&gt; 11199041820998981060
...

View all 299 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🔄 Datadog auto-retried 2 jobs - 0 passed on retry View in Datadog

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 54.08% (-0.04%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 40bbc2f | Docs | Datadog PR Page | Give us feedback!

@pr-commenter

pr-commenter Bot commented Jul 17, 2026

Copy link
Copy Markdown

Benchmarks [ tracer ]

Benchmark execution time: 2026-07-17 14:10:48

Comparing candidate commit 40bbc2f in PR branch leiyks/dd-trace-php-v2 with baseline commit a70313e in branch master.

Some scenarios are present only in baseline or only in candidate runs. If you didn't create or remove some scenarios in your branch, this maybe a sign of crashed benchmarks 💥💥💥
Check Gitlab CI job log to find if any benchmark has crashed.

Scenarios present only in baseline:

  • MessagePackSerializationBench/benchMessagePackSerialization
  • MessagePackSerializationBench/benchMessagePackSerialization-opcache

Found 5 performance improvements and 10 performance regressions! Performance is the same for 175 metrics, 0 unstable metrics.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

scenario:ContextPropagationBench/benchExtractHeaders64Bit-opcache

  • 🟩 execution_time [-764.363ns; -727.637ns] or [-39.461%; -37.565%]

scenario:ContextPropagationBench/benchExtractTraceContext128Bit-opcache

  • 🟩 execution_time [-821.443ns; -694.557ns] or [-31.389%; -26.540%]

scenario:ContextPropagationBench/benchExtractTraceContext64Bit-opcache

  • 🟥 execution_time [+771.454ns; +832.546ns] or [+88.368%; +95.366%]

scenario:ContextPropagationBench/benchInject128Bit-opcache

  • 🟥 execution_time [+684.077ns; +771.923ns] or [+40.622%; +45.839%]

scenario:ContextPropagationBench/benchInject64Bit-opcache

  • 🟥 execution_time [+583.434ns; +700.566ns] or [+25.170%; +30.223%]

scenario:HookBench/benchHookOverheadTraceMethod-opcache

  • 🟥 mem_peak [+64.182KB; +64.185KB] or [+3.009%; +3.009%]

scenario:SamplingRuleMatchingBench/benchGlobMatching1-opcache

  • 🟥 execution_time [+56.105ns; +193.095ns] or [+2.129%; +7.329%]

scenario:SamplingRuleMatchingBench/benchRegexMatching1-opcache

  • 🟩 execution_time [-119.821ns; -41.579ns] or [-7.226%; -2.507%]

scenario:SamplingRuleMatchingBench/benchRegexMatching2-opcache

  • 🟩 execution_time [-209.228ns; -98.972ns] or [-12.213%; -5.777%]

scenario:SamplingRuleMatchingBench/benchRegexMatching4-opcache

  • 🟩 execution_time [-127.393ns; -46.407ns] or [-7.615%; -2.774%]

scenario:SpanBench/benchOpenTelemetryAPI

  • 🟥 mem_peak [+978.759KB; +978.765KB] or [+2.052%; +2.052%]

scenario:SpanBench/benchOpenTelemetryAPI-opcache

  • 🟥 mem_peak [+897.186KB; +897.197KB] or [+2.006%; +2.006%]

scenario:SpanBench/benchOpenTelemetryInteroperability

  • 🟥 execution_time [+5.330µs; +8.816µs] or [+2.792%; +4.619%]

scenario:SpanBench/benchOpenTelemetryInteroperability-opcache

  • 🟥 execution_time [+4.989µs; +8.417µs] or [+2.787%; +4.701%]

scenario:TraceAnnotationsBench/benchTraceAnnotationOverhead-opcache

  • 🟥 mem_peak [+64.184KB; +64.184KB] or [+2.989%; +2.989%]

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