Skip to content

Add PHP single-step APM instrumentation support#257

Merged
Kyle-Neale merged 4 commits into
masterfrom
kyle.neale/php-ssi
Jul 1, 2026
Merged

Add PHP single-step APM instrumentation support#257
Kyle-Neale merged 4 commits into
masterfrom
kyle.neale/php-ssi

Conversation

@Kyle-Neale

@Kyle-Neale Kyle-Neale commented May 14, 2026

Copy link
Copy Markdown
Contributor

Extends DD_APM_INSTRUMENTATION_ENABLED to cover PHP, matching the existing SSI path for Python, Node.js, and Ruby. A PHP app pushed with this buildpack alongside php_buildpack gets the tracer + profiler just by setting DD_APM_INSTRUMENTATION_ENABLED=true.

Refs FRAGENT-3448.

How it works

The PHP arm of enable_apm_ssi() in lib/run-datadog.sh fetches datadog-setup.php at app start and installs it against the php_buildpack-staged PHP binary — same shape as pip install ddtrace / npm install dd-trace / gem install ddtrace. No tracer payload in the buildpack ZIP.

DD_TRACE_PHP_VERSION (default 1.19.2) pins the tracer per app.

Notes worth knowing

  • We trigger $HOME/.bp/bin/rewrite "$HOME/php/etc" ourselves before invoking PHP. php_buildpack's own rewriter sorts alphabetically after 01-run-datadog.sh, so without this the installer hits mkdir: @{TMPDIR}/.... The rewriter is idempotent.
  • PHPRC=$HOME/php/etc and --install-dir=$HOME/.datadog/dd-library-php — the binary bakes a build-time ini path that doesn't exist at runtime, and /opt/datadog isn't writable as vcap.
  • Web + sidecars race to install. We use a lock dir (php-ssi.installing) + done marker (php-ssi.installed): the winner installs, losers block up to 120s for the done marker before continuing — otherwise PHP-FPM in the losing process would exec before ddtrace.so is in place.
  • curl is bounded (--connect-timeout 10 --max-time 60) so a slow mirror can't hang container startup.
  • Install failure logs a warning and the app boots uninstrumented, matching the other languages.

@github-actions github-actions Bot added the documentation Documentation related changes label May 14, 2026
Kyle-Neale added a commit that referenced this pull request May 14, 2026
The buildpack now ships dd-library-php and writes the tracer ini at
runtime (PR #257), so the app-side workarounds are no longer needed:

- Drop .bp-config/php/php.ini.d/datadog.ini — buildpack owns this now.
- Drop manifest command override and DD_TRACE_*_ENABLED env vars.
- Switch WEB_SERVER from php-server (n/a on TAS) to httpd
  (spike-validated to propagate PHP_INI_SCAN_DIR).
- Drop the dd-library-php tarball download from build.sh; only Composer
  vendoring remains.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Kyle-Neale
Kyle-Neale marked this pull request as ready for review May 19, 2026 14:25
@Kyle-Neale
Kyle-Neale requested a review from a team as a code owner May 19, 2026 14:25
gh-worker-dd-mergequeue-cf854d Bot pushed a commit that referenced this pull request May 20, 2026
Add PHP sample app with APM tracing and profiling

Adds examples/cf-php-sample-app/ following the established pattern for
sample apps in this repo (Python, Ruby, Node.js, Go, Java, Nginx). The
app uses Slim Framework, the built-in PHP HTTP server via php_buildpack,
and pre-bundles dd-trace-php 1.19.1 native extensions in build.sh so it
can be staged on offline Tanzu Application Service environments.

FRAGENT-3448

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Refine PHP sample app to match other examples

- Set explicit run command in manifest.yml (parity with python/ruby/node)
- Drop redundant DD_TRACE_ENABLED (default once extension is loaded)
- Drop PHP_EXTENSIONS override; buildpack defaults (bz2, zlib, curl) suffice
- Wildcard examples/*/extensions/ in .gitignore to match existing pattern
- Commit composer.lock for reproducible offline builds

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Bump PHP sample app memory to 1024M

Avoids startup failures during initial deployment; can tune down later.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Pin PHP to 8.2.* in PHP sample app composer.json

`^8.2` matches the entire 8.x line, so composer install would resolve
to PHP 8.5+ and pull packages whose dd-trace-php native extensions
aren't built for. Tightening to `8.2.*` keeps the lock file aligned
with the `{PHP_82_LATEST}` runtime the buildpack provisions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Bump PHP sample app disk_quota to 2 GB

The buildpack-side dd-library-php payload adds ~232 MB to the droplet,
on top of php_buildpack's own PHP runtime. The default 1 GB CF disk
quota isn't enough — restage fails with "No space left on device" while
extracting the PHP runtime. 2 GB leaves comfortable headroom.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Strip PHP SSI workarounds from sample app

The buildpack now ships dd-library-php and writes the tracer ini at
runtime (PR #257), so the app-side workarounds are no longer needed:

- Drop .bp-config/php/php.ini.d/datadog.ini — buildpack owns this now.
- Drop manifest command override and DD_TRACE_*_ENABLED env vars.
- Switch WEB_SERVER from php-server (n/a on TAS) to httpd
  (spike-validated to propagate PHP_INI_SCAN_DIR).
- Drop the dd-library-php tarball download from build.sh; only Composer
  vendoring remains.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Enable PHP SSI on sample app via DD_APM_INSTRUMENTATION_ENABLED

Co-authored-by: kyle.neale <kyle.neale@datadoghq.com>
Kyle-Neale added a commit that referenced this pull request May 26, 2026
- block sidecar race: separate install-lock from done-marker so losing
  processes wait until the winner finishes instead of exec()ing PHP-FPM
  before ddtrace.so is in place
- prefer ${HOME}/php/bin/php over command -v php so PHPRC derives the
  runtime ini dir rather than a system PHP's
- bound curl with --connect-timeout 10 --max-time 60
- drop Java from README runtime list; enable_apm_ssi has no Java arm

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Kyle-Neale
Kyle-Neale force-pushed the kyle.neale/php-ssi branch from 0500e36 to 973038a Compare May 26, 2026 19:16
Adds a PHP arm to enable_apm_ssi() so a PHP app pushed with this
buildpack alongside php_buildpack gets dd-library-php loaded just by
setting DD_APM_INSTRUMENTATION_ENABLED=true — same shape as the
existing Python, Node.js, and Ruby SSI flows.

At app start, the PHP arm fetches datadog-setup.php from
github.com/DataDog/dd-trace-php/releases and runs it against the
php_buildpack-staged PHP binary. DD_TRACE_PHP_VERSION (default 1.19.2)
pins the tracer per app. No tracer payload is bundled into the
buildpack ZIP.

Concurrency: .profile.d is sourced once per process, so web + each
sidecar race to install. A lock dir (php-ssi.installing) plus a done
marker (php-ssi.installed) gate the install so the winner runs once
and losers block up to 120s for the done marker — otherwise PHP-FPM
in the losing process would exec before ddtrace.so is in place.

Also tightens Node.js and Ruby gating to require their respective
buildpacks to be declared, not just npm/gem on PATH — this buildpack
ships its own Ruby which was previously triggering ddtrace installs
on non-Ruby apps.

Refs FRAGENT-3448.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Kyle-Neale
Kyle-Neale force-pushed the kyle.neale/php-ssi branch from 973038a to 10e3990 Compare May 27, 2026 12:29
@Kyle-Neale Kyle-Neale added the changelog/Added Added features results into a minor version bump label Jun 1, 2026
Kyle-Neale and others added 3 commits June 30, 2026 10:50
Mirrors the python branch's "detected pip command:" line so the chosen
PHP binary is visible in `cf logs`, and echoes the datadog-setup.php
release URL before the curl so 404s (bad DD_TRACE_PHP_VERSION) and
network failures point at the cause directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
php_buildpack runs `composer install` during staging and places vendor
at $LIBDIR/vendor (default LIBDIR=lib), so the container ends up with
/home/vcap/app/lib/vendor/. Index.php was requiring
__DIR__/../vendor/autoload.php which doesn't exist there, so every
request 500'd in the autoloader before the app could send custom
metrics via DataDog\DogStatsd.

Pin composer's vendor-dir to lib/vendor so local builds and the
staging-time install land in the same place, and update the require
path to match. `cf push` now works standalone for online envs — no
./build.sh required, in line with the other sample apps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Follow-up to the vendor-dir change — `rm -rf vendor` was a no-op once
composer was pinned to write into lib/vendor. Point the cleanup at the
right path so re-running build.sh from a populated worktree actually
starts from a clean slate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@Kyle-Neale
Kyle-Neale merged commit 25b4c7f into master Jul 1, 2026
6 checks passed
@Kyle-Neale
Kyle-Neale deleted the kyle.neale/php-ssi branch July 1, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/Added Added features results into a minor version bump documentation Documentation related changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants