Skip to content

feat(tracer): send traces as V1 payloads through the libdatadog builder FFI - #4046

Draft
Leiyks wants to merge 10 commits into
v2from
leiyks/dd-trace-php-v2
Draft

Leiyks wants to merge 10 commits into
v2from
leiyks/dd-trace-php-v2

Conversation

@Leiyks

@Leiyks Leiyks commented Jul 17, 2026 •

Copy link
Copy Markdown
Contributor

Migrate the tracer to the V1 Efficient Trace Payload protocol (APMLP-1197). This PR is also part of the V2 release, so it carries the V2 deprecations and removals listed below.

  • Senders: closed spans are serialized into a libdatadog V1 payload builder. The sidecar sends them to /v1.0/traces when the agent's /info advertises it and downgrades to v0.4 otherwise. The in-process sender keeps the v0.4 wire, downgraded from the same builder by libdatadog.
  • Top-level: with the sidecar sender, the tracer marks top-level spans with _dd.top_level and sends client_computed_top_level.
  • Span data: one typed SpanData::$attributes store, with $env, $version, $component and $spanKind (DDTrace\SpanKind) properties. Span links and events carry native typed attributes. Process tags, the OTLP export marker, git metadata and the hostname are payload-level.
  • Introspection: dd_trace_serialize_closed_spans() returns the V1 payload view and the tests are migrated to it. The request-replayer decodes V1 into the same JSON view.

Before merge

Behaviour changes

  • The sidecar is the default trace sender on all PHP versions (it was PHP 8.3+ and Windows only); DD_TRACE_SIDECAR_TRACE_SENDER=0 selects the in-process sender.
  • New DD_TRACE_AGENT_PROTOCOL_VERSION: 1.0 (default) sends V1 when the agent advertises /v1.0/traces, 0.4 always sends v0.4.
  • Span, link and event attribute values keep their PHP type: numbers and bools are sent typed and arrays nest. http.status_code, env/version and ids stay strings.
  • SpanData::$meta and $metrics are views onto $attributes (both deprecated). $meta reads list every property-backed key that is set, so legacy DDTrace\Span::getAllTags() now also returns service.name, operation.name and span.type.
  • Writing service.name, resource.name, operation.name, span.type, env, version, component, span.kind or error.ignored through $meta sets the matching span property; $attributes keys stay raw.
  • Legacy DDTrace\Span: setTag($k, null) and setMetric($k, null) remove the key, bool tags become "true"/"false" (they were "1"/""), and an object passed to log() as the message is sent as a map of its public properties.
  • Web root spans default component to "web"; frameworks still override it, and CLI root spans get no default.
  • #[DDTrace\Trace] gains $attributes, $kind and $component. A non-empty $tags still applies but raises E_DEPRECATED.
  • Removed functions: DDTrace\Config\integration_analytics_enabled(), DDTrace\Config\integration_analytics_sample_rate(), and the internal dd_trace_serialize_msgpack(), dd_trace_send_traces_via_thread(), dd_trace_buffer_span(), dd_trace_coms_trigger_writer_flush(), dd_trace_reset() and dd_trace_noop().
  • Removed config: DD_TRACE_ANALYTICS_ENABLED, DD_TRACE_<INTEGRATION>_ANALYTICS_ENABLED and DD_TRACE_<INTEGRATION>_ANALYTICS_SAMPLE_RATE (with their DD_<INTEGRATION>_ANALYTICS_* aliases), and DD_TRACE_WARN_LEGACY_DD_TRACE.
  • An analytics.event tag is no longer mapped to _dd1.sr.eausr. Tag::ANALYTICS_KEY and TraceAnalyticsProcessor::normalizeAnalyticsValue() are deprecated no-ops.
  • dd_trace_serialize_closed_spans() returns the V1 payload view: payload fields, attributes, and chunks, each with trace_id, priority, origin, sampling_mechanism and spans.
  • The hostname (DD_TRACE_REPORT_HOSTNAME) is a payload field: the root span's $meta no longer has _dd.hostname (Tag::HOSTNAME). The v0.4 downgrade still writes it on each trace's local root.
  • SpanLink::$droppedAttributesCount is no longer sent (V1 links have no such field).
  • SpanLink and SpanEvent no longer implement JsonSerializable.
  • On the v0.4 wire (agents without /v1.0/traces, and the in-process sender), a span without its own version gets the payload app_version (DD_VERSION, else the root span's version). This is libdatadog's existing V1 to v0.4 mapping.

Deprecated functions (runtime E_DEPRECATED):

Function Replacement
DDTrace\trace_id() DDTrace\root_span()->traceId (hex) or DDTrace\logs_correlation_trace_id()
DDTrace\current_context() the DDTrace\root_span() properties or DDTrace\generate_distributed_tracing_headers()
ddtrace_config_app_name() dd_trace_env_config('DD_SERVICE')
ddtrace_config_distributed_tracing_enabled() dd_trace_env_config('DD_DISTRIBUTED_TRACING')
ddtrace_config_trace_enabled() dd_trace_env_config('DD_TRACE_ENABLED')
dd_trace_set_trace_id() DDTrace\set_distributed_tracing_context()
dd_trace_compile_time_microseconds() none
dd_trace_function() DDTrace\trace_function()
dd_trace_method() DDTrace\trace_method()

CI notes for reviewers

  • CI runs test agent v1.67.0, which includes feat(trace): decode List/KeyValue/Bytes attribute values in v1 payloads dd-apm-test-agent#422 (V1 attribute flattening). That version forwards /info to DD_TRACE_AGENT_URL, so jobs without a request-replayer use the new test-agent-standalone service.
  • CI uses the request-replayer 5.0 and php-request-replayer-5.0_windows images, both built from this branch's dockerfiles/services/request-replayer. Rebuild them if that source changes.
  • Snapshot comparisons ignore meta._dd.p.dm and metrics._sampling_priority_v1. The test agent's V1 conversion drops sampling mechanism 0 and copies the chunk priority onto every span (APMAPI-1545). Re-blessing would be flaky: a sidecar's first flushes go out as v0.4 before /info is known.

@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

❌ Errors

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

🚦 25 Pipeline jobs failed

DataDog/apm-reliability/dd-trace-php | test_web_symfony_latest: [8.5, cli-server] — ❌ 1 test failed · 🔧 Needs a code fix, caused by this PR

View more details · View in GitLab

❌ testScenarioGetToMissingRoute from symfony-latest-test.DDTrace\Tests\Integrations\Symfony\Latest\CommonScenariosTest
       &#39;#8 &#39;
                                &#39;{path}/tests/Frameworks/Symfony/Latest/vendor/symfony/http-kernel/HttpKernel.php(80): &#39;
                                &#39;Symfony\\Component\\HttpKernel\\HttpKernel-&gt;handleRaw()\n&#39;
                                &#39;#9 &#39;
                                &#39;{path}/tests/Frameworks/Symfony/Latest/vendor/symfony/http-kernel/Kernel.php(155): &#39;
                                &#39;Symfony\\Component\\HttpKernel\\HttpKernel-&gt;handle()\n&#39;
                                &#39;#10 &#39;
                                &#39;{path}/tests/Frameworks/Symfony/Latest/vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php(34): &#39;
                                &#39;Symfony\\Component\\HttpKernel\\Kernel-&gt;handle()\n&#39;
                                &#39;#11 &#39;
...
DataDog/apm-reliability/dd-trace-php | test_web_symfony_23: [7.2, apache2handler] — ❄️ 3 known flaky tests

View more details · View in GitLab

↳ ❄️ Known flaky: testScenarioGetToMissingRoute from tests/Integrations/Symfony/V2_3.DDTrace\Tests\Integrations\Symfony\V2_3\CommonScenariosTest

↳ ❄️ Known flaky: testScenarioGetWithException from tests/Integrations/Symfony/V2_3.DDTrace\Tests\Integrations\Symfony\V2_3\CommonScenariosTest

↳ and 1 more — View all
DataDog/apm-reliability/dd-trace-php | test_web_symfony_73: [8.3, cli-server] — ❄️ 1 known flaky test

View more details · View in GitLab

↳ ❄️ Known flaky: testScenarioGetToMissingRoute from symfony-73-test.DDTrace\Tests\Integrations\Symfony\V7_3\CommonScenariosTest

View all 25 failed jobs.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
• Patch Coverage: 88.94%
• Overall Coverage: 78.02% (+0.03%)

Useful? React with 👍 / 👎

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

@pr-commenter

pr-commenter Bot commented Jul 17, 2026 •

Copy link
Copy Markdown

Benchmarks [ tracer ]

Benchmark execution time: 2026-11-03 14:23:08

Comparing candidate commit d5175e4 in PR branch leiyks/dd-trace-php-v2 with baseline commit 1fe5fcf in branch v2.

📊 Benchmarking dashboard

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-opcache
  • MessagePackSerializationBench/benchMessagePackSerialization

Found 21 performance improvements and 27 performance regressions! Performance is the same for 142 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/benchExtractTraceContext128Bit-opcache

  • 🟥 execution_time [+832.346ns; +957.654ns] or [+44.798%; +51.542%]

scenario:ContextPropagationBench/benchInject128Bit-opcache

  • 🟩 execution_time [-854.539ns; -753.461ns] or [-35.253%; -31.083%]

scenario:EmptyFileBench/benchEmptyFileBaseline

  • 🟥 mem_peak [+128.984KB; +128.984KB] or [+2.445%; +2.445%]

scenario:EmptyFileBench/benchEmptyFileBaseline-opcache

  • 🟩 execution_time [-333.147µs; -185.973µs] or [-8.683%; -4.847%]

scenario:EmptyFileBench/benchEmptyFileDdprof

  • 🟥 mem_peak [+126.606KB; +130.929KB] or [+2.395%; +2.477%]

scenario:EmptyFileBench/benchEmptyFileOverhead

  • 🟥 mem_peak [+128.984KB; +128.984KB] or [+2.445%; +2.445%]
  • 🟩 execution_time [-277.065µs; -99.355µs] or [-7.133%; -2.558%]

scenario:EmptyFileBench/benchEmptyFileOverhead-opcache

  • 🟩 execution_time [-353.665µs; -180.135µs] or [-8.793%; -4.479%]

scenario:HookBench/benchHookOverheadInstallHookOnFunction

  • 🟥 mem_peak [+88.536KB; +88.536KB] or [+2.178%; +2.178%]

scenario:HookBench/benchHookOverheadInstallHookOnMethod

  • 🟥 mem_peak [+88.536KB; +88.536KB] or [+2.178%; +2.178%]

scenario:HookBench/benchHookOverheadTraceFunction

  • 🟥 mem_peak [+225.231KB; +225.234KB] or [+4.992%; +4.992%]

scenario:HookBench/benchHookOverheadTraceFunction-opcache

  • 🟥 execution_time [+4.648µs; +10.695µs] or [+2.794%; +6.429%]
  • 🟥 mem_peak [+94.006KB; +94.009KB] or [+4.460%; +4.460%]

scenario:HookBench/benchHookOverheadTraceMethod

  • 🟥 mem_peak [+225.229KB; +225.236KB] or [+4.922%; +4.922%]

scenario:HookBench/benchHookOverheadTraceMethod-opcache

  • 🟥 mem_peak [+127.998KB; +128.001KB] or [+5.987%; +5.987%]

scenario:HookBench/benchWithoutHook

  • 🟥 mem_peak [+88.552KB; +88.552KB] or [+2.179%; +2.179%]

scenario:LaravelBench/benchLaravelBaseline

  • 🟥 mem_peak [+129.016KB; +129.016KB] or [+2.445%; +2.445%]

scenario:LaravelBench/benchLaravelDdprof

  • 🟥 mem_peak [+123.935KB; +128.966KB] or [+2.343%; +2.438%]

scenario:LaravelBench/benchLaravelOverhead

  • 🟥 mem_peak [+129.016KB; +129.016KB] or [+2.445%; +2.445%]

scenario:LogsInjectionBench/benchLogsInfoBaseline-opcache

  • 🟥 execution_time [+311.745ns; +379.655ns] or [+19.555%; +23.815%]

scenario:LogsInjectionBench/benchLogsInfoInjection

  • 🟩 execution_time [-1.227µs; -0.972µs] or [-18.033%; -14.290%]

scenario:LogsInjectionBench/benchLogsInfoInjection-opcache

  • 🟩 execution_time [-1.314µs; -0.997µs] or [-13.319%; -10.097%]

scenario:LogsInjectionBench/benchLogsNullBaseline-opcache

  • 🟩 execution_time [-1.355µs; -1.209µs] or [-6.155%; -5.493%]

scenario:LogsInjectionBench/benchLogsNullInjection-opcache

  • 🟩 execution_time [-1317.116ns; -538.884ns] or [-5.987%; -2.449%]

scenario:PDOBench/benchPDOBaseline

  • 🟥 mem_peak [+97.480KB; +97.480KB] or [+2.377%; +2.377%]

scenario:SamplingRuleMatchingBench/benchRegexMatching1-opcache

  • 🟥 execution_time [+42.614ns; +116.986ns] or [+2.648%; +7.270%]

scenario:SamplingRuleMatchingBench/benchRegexMatching2-opcache

  • 🟩 execution_time [-155.140ns; -73.060ns] or [-8.948%; -4.214%]

scenario:SpanBench/benchOpenTelemetryAPI

  • 🟥 execution_time [+10.154µs; +14.433µs] or [+2.790%; +3.965%]

scenario:SpanBench/benchOpenTelemetryAPI-opcache

  • 🟥 execution_time [+9.211µs; +15.325µs] or [+2.771%; +4.610%]

scenario:SpanBench/benchOpenTelemetryInteroperability

  • 🟥 execution_time [+7.444µs; +12.391µs] or [+3.589%; +5.974%]
  • 🟩 mem_peak [-809.837KB; -809.360KB] or [-2.694%; -2.693%]

scenario:SpanBench/benchOpenTelemetryInteroperability-opcache

  • 🟥 execution_time [+7.622µs; +12.621µs] or [+3.995%; +6.615%]
  • 🟩 mem_peak [-816.853KB; -816.184KB] or [-3.014%; -3.012%]

scenario:SymfonyBench/benchSymfonyBaseline

  • 🟥 mem_peak [+129.016KB; +129.016KB] or [+2.445%; +2.445%]
  • 🟩 execution_time [-297.906µs; -160.654µs] or [-3.727%; -2.010%]

scenario:SymfonyBench/benchSymfonyBaseline-opcache

  • 🟩 execution_time [-274.778µs; -190.982µs] or [-3.387%; -2.354%]

scenario:SymfonyBench/benchSymfonyDdprof

  • 🟥 mem_peak [+109.035KB; +124.402KB] or [+2.058%; +2.348%]
  • 🟩 execution_time [-363.018µs; -270.622µs] or [-3.821%; -2.848%]

scenario:SymfonyBench/benchSymfonyDdprof-opcache

  • 🟩 execution_time [-381.416µs; -279.784µs] or [-4.024%; -2.952%]

scenario:SymfonyBench/benchSymfonyOverhead

  • 🟥 mem_peak [+129.016KB; +129.016KB] or [+2.445%; +2.445%]
  • 🟩 execution_time [-390.950µs; -270.130µs] or [-4.405%; -3.044%]

scenario:SymfonyBench/benchSymfonyOverhead-opcache

  • 🟩 execution_time [-439.472µs; -314.448µs] or [-4.877%; -3.489%]

scenario:TraceAnnotationsBench/benchTraceAnnotationOverhead

  • 🟥 mem_peak [+143.342KB; +143.345KB] or [+3.127%; +3.127%]

scenario:TraceAnnotationsBench/benchTraceAnnotationOverhead-opcache

  • 🟥 mem_peak [+128.032KB; +128.032KB] or [+5.948%; +5.948%]

scenario:TraceFlushBench/benchFlushTrace

  • 🟩 execution_time [-44.804µs; -35.496µs] or [-14.351%; -11.370%]

scenario:TraceFlushBench/benchFlushTrace-opcache

  • 🟩 execution_time [-38.139µs; -25.461µs] or [-12.214%; -8.154%]

scenario:TraceSerializationBench/benchSerializeTrace

  • 🟩 execution_time [-97.854µs; -86.946µs] or [-25.279%; -22.461%]

scenario:TraceSerializationBench/benchSerializeTrace-opcache

  • 🟩 execution_time [-78.842µs; -70.358µs] or [-24.887%; -22.209%]

@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch from 2531886 to b29cd49 Compare July 27, 2026 15:20
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch 3 times, most recently from 10c7edf to 84351df Compare August 6, 2026 12:39
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch 2 times, most recently from 73c262e to 0d3d03d Compare August 25, 2026 15:50
@Leiyks
Leiyks marked this pull request as ready for review August 26, 2026 11:56
@Leiyks
Leiyks requested review from a team as code owners August 26, 2026 11:56
@Leiyks
Leiyks requested review from dd-oleksii, greghuels and tabgok and removed request for a team August 26, 2026 11:56

@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: 0d3d03d6f7

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread tracer/serializer.c Resolved
Comment thread tracer/span_stats.c Resolved
Comment thread tracer/span.c Resolved
@Leiyks
Leiyks marked this pull request as draft August 26, 2026 16:33
@Leiyks Leiyks changed the title feat(tracer): align C span code with v1-compatible stub API (v2 groundwork) WIP: feat(tracer): align C span code with v1-compatible stub API (v2 groundwork) Aug 26, 2026
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch from f553cb8 to a8f30bd Compare September 15, 2026 11:45
Comment thread components-rs/bytes.rs Resolved
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
Comment thread tests/Integrations/PDO/PDOTest.php Resolved
Comment thread tracer/hook/uhook_attributes.c Resolved
Comment thread tracer/integrations/exec_integration.c Resolved
Comment thread tracer/auto_flush.c Resolved
Comment thread tracer/code_origins.c Resolved
Comment thread tracer/ddtrace_arginfo.h Resolved
Comment thread tracer/ddtrace.stub.php Resolved
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch 2 times, most recently from 6dd5b69 to 47b3817 Compare October 15, 2026 14:25
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
Comment thread tracer/serializer.c Resolved
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch from 47b3817 to dd1b7e6 Compare October 26, 2026 14:18
@Leiyks
Leiyks changed the base branch from master to v2 October 26, 2026 14:19
@pr-commenter

pr-commenter Bot commented Oct 26, 2026 •

Copy link
Copy Markdown

Benchmarks [ profiler ]

Benchmark execution time: 2026-11-03 15:02:34

Comparing candidate commit fcdf84a in PR branch leiyks/dd-trace-php-v2 with baseline commit 1fe5fcf in branch v2.

📊 Benchmarking dashboard

Found 0 performance improvements and 0 performance regressions! Performance is the same for 24 metrics, 6 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 ----------------------------------'

Unstable benchmarks

These benchmarks have a confidence interval too wide to call a change; treat them as noise rather than signal.

scenario:php-profiler-exceptions-control

  • unstable cpu_system_time [-6.995ms; +1.381ms] or [-14.002%; +2.765%]
  • unstable cpu_user_time [-1.892ms; +5.833ms] or [-3.359%; +10.357%]

scenario:php-profiler-exceptions-with-profiler

  • unstable cpu_system_time [-6.601ms; +1.726ms] or [-12.671%; +3.312%]

scenario:php-profiler-exceptions-with-profiler-and-timeline

  • unstable cpu_system_time [-9.897ms; +1.978ms] or [-18.354%; +3.668%]
  • unstable cpu_user_time [-2.201ms; +12.293ms] or [-2.904%; +16.221%]

scenario:php-profiler-timeline-memory-control

  • unstable cpu_system_time [-3.777ms; +7.011ms] or [-7.948%; +14.754%]

…er FFI

Serialize closed spans into a libdatadog TracerPayloadV1Builder (Box-per-node pointer handles) and send them to the sidecar as /v1.0/traces, with the sidecar negotiating /info and downgrading to v0.4 for agents that lack it. The in-process sender keeps the v0.4 wire, transcoded from the same builder.

Span tags live in a single typed attributes store; SpanData::$meta and $metrics are views onto it. Process tags and the OTLP export marker are TracerPayload attributes (the v0.4 downgrade puts them on each chunk's first span), and span links and events carry native attributes. DD_TRACE_AGENT_PROTOCOL_VERSION=0.4 forces v0.4.

Bump libdatadog to the V1 FFI branch and port components-rs to the new rate limiter API.
Use typed SpanData::$attributes and the promoted env/version/component/span_kind properties instead of $meta/$metrics string conversions in the userland integrations and the OpenTelemetry bridge.

Drop the userland App Analytics plumbing (addTraceAnalyticsIfEnabled, requiresExplicitTraceAnalyticsEnabling, markForTraceAnalytics and the per-integration candidates). TraceAnalyticsProcessor::normalizeAnalyticsValue and Tag::ANALYTICS_KEY are now deprecated no-ops; the serializer still maps an analytics.event tag to _dd1.sr.eausr.
dd_trace_serialize_closed_spans() now reports the V1 shape: a typed attributes map with promoted fields (span_kind, component, sampling_priority, ...) and native span links and events. Migrate the phpt, PHPUnit and snapshot tests to it, and add coverage for the V1 and v0.4 wires, span attributes, ignoreError and the default root component.

Remove tests for the retired userland msgpack serializer and thread sender (dd_trace_serialize_msgpack, dd_trace_send_traces_via_thread, the in-process background sender capability tests) and for the removed App Analytics trace search config.
Add a msgpack V1 decoder to the request-replayer and advertise /v1.0/traces in its /info, so the PHP test suite can inspect V1 payloads. Move the CI service to the 5.0 image and force-pull the Windows service images so a runner with a stale cached digest does not skip a rebuilt image. Add APM_TRACING_EFFICIENT_PAYLOAD to the System Tests matrix.
…merge

Clone system-tests at SYSTEM_TESTS_REF (default leiyks/php-v1-payload,
DataDog/system-tests#7843) from SYSTEM_TESTS_REPO.
@Leiyks
Leiyks force-pushed the leiyks/dd-trace-php-v2 branch from ecae624 to d5175e4 Compare November 3, 2026 13:15
The test disabled telemetry and the sidecar trace sender, so nothing started the sidecar that fetches the agent /info, and span_events was never advertised. Drop the telemetry opt-out and assert await_agent_info succeeds.
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.

3 participants