perf(config): cache sys getenv by morrisonlevi · Pull Request #3670 · DataDog/dd-trace-php

@morrisonlevi morrisonlevi changed the title perf(config): caches sys getenv on minit perf(config): cache sys getenv on minit

Feb 24, 2026

@morrisonlevi morrisonlevi changed the title perf(config): cache sys getenv on minit perf(config): cache sys getenv

Feb 24, 2026

bwoebi

bwoebi

bwoebi

bwoebi

bwoebi

In rinit, calling system getenv when a SAPI env var isn't found is
slow enough it shows up in profiles. glibc's getenv does a linear
scan on the environ and does strncmp on the members, so we can
definitely do better.

We save it in minit so it's available for SYSTEM_INI variables and
again on the first request.

This is also arguably more correct: system environment variables map
to a system INI setting, which shouldn't change at runtime.

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

@morrisonlevi

Replace zai_getenv_ex/zai_getenv with two focused functions:
- zai_sapi_getenv: borrows value from the SAPI environment
- zai_sys_getenv: borrows value from the process environment

Both return zai_option_str instead of writing into a caller-supplied
buffer, eliminating the ZAI_ENV_BUFFER_* error codes and the scratch
buffer indirection throughout callers.

Update config, config_ini, and otel_config to use the new API. Rename
zai_config_get_cached_env_value to zai_config_sys_getenv_cached to
return zai_option_str directly. Add ZAI_OPTION_STRL macro and
zai_option_str_eq helper to string.h. Remove now-obsolete error.cc
env tests.
- Remove !env_to_ini_name guard from zai_config_ini_rinit so SAPI env
  vars (e.g. Apache SetEnv) are always consulted at RINIT, not only
  when env_to_ini_name is NULL. This restores ini->modified being set
  from env vars, which the Rust RC client relies on to detect
  user-set values before applying dynamic config overrides.

- Add SAPI env check to zai_config_find_and_set_value at first RINIT
  so values are visible before zai_config_ini_rinit runs. Code such as
  the signal handler setup for DD_TRACE_HEALTH_METRICS_ENABLED (Apache
  SetEnv) reads decoded config between first_time_rinit and
  zai_config_ini_rinit and requires SAPI env to be present at that
  point.

- Remove erroneous manual zai_config_first_time_rinit(true) call in
  the perdir/multi-consumer INI test; REQUEST_BEGIN already triggers
  it through the extension RINIT handler.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

morrisonlevi

@morrisonlevi

bwoebi

bwoebi added a commit that referenced this pull request

Mar 20, 2026
…dd-update

* 'master' of github.com:DataDog/dd-trace-php:
  feat(sidecar): add thread mode as fallback connection for restricted environments (#3573)
  Migrate deprecated GitLab runner tags (#3715)
  Adds process tags to remote config payload (#3658)
  perf(config): cache sys getenv (#3670)
  Fixes the tag name for process tags (#3709)
  Fix debugger ephemerals handling (#3685)
  Fix #3651: Prevent crash during shutdown in Frankenphp (#3662)
  Add dynamic instrumentation and exception replay to startup logging (#3667)
  chore: bump bytes crate from 1.9.0 to 1.11.1 to address CVE-2026-25541 (#3669)
  Merge pull request #3701 from DataDog/brian.marks/add-ksr-tag
  ci: fix Windows job flakiness caused by dirty workspace (#3694)
  Fixup CI owner association (#3704)
  Add Rust rewrite of the AppSec helper alongside the C++ implementation
  Remove debug instruction
  Fix script order
  debug
  Fix exploration logic
  chore(ci): add final_status property on junit XML [APMSP-2610]
  Fix DD_TRACE_SYMFONY_HTTP_ROUTE=false
  Optimize Symfony http.route caching with path map approach