Skip to content

Add PROFILER_EXCLUDE_PATHS to skip paths in profiler sampling#242

Merged
diolektor merged 1 commit into
mainfrom
feature/profiler-exclude-paths
Jun 23, 2026
Merged

Add PROFILER_EXCLUDE_PATHS to skip paths in profiler sampling#242
diolektor merged 1 commit into
mainfrom
feature/profiler-exclude-paths

Conversation

@diolektor

Copy link
Copy Markdown
Contributor

Summary

Adds PROFILER_EXCLUDE_PATHS — comma-separated glob patterns whose matching request paths are kept out of PROFILER_SAMPLE_RATE sampling. This stops framework self-traffic (Symfony's /_profiler and /_wdt toolbar requests, Laravel Debugbar/Telescope) from polluting captured profiles when sampling is enabled in production.

Behavior

  • Sampling only. Exclusion gates the sample_rate branch. An explicit trigger (x-oxphp-profile header, OXPROF cookie, __oxprof query) still profiles an excluded path — so you can deliberately profile /_profiler itself while keeping it out of background sampling.
  • Glob syntax shared with PHP_DENY_PATHS: * does not cross /, ** does, leading / optional. Cover a bare path and its subtree by listing both, e.g. PROFILER_EXCLUDE_PATHS=/_profiler,/_profiler/**,/_wdt/**.
  • Config only, no built-in defaults. Unset/empty excludes nothing. A malformed glob fails fast at startup.
  • Matches the raw request path at RequestReceived (before routing) — no percent-decoding or .. normalization. The pattern syntax is shared with PHP_DENY_PATHS, not the matched input; this is documented and intentional (exclusion only suppresses sampling overhead, it is not a security boundary).

Changes

  • Config: new PROFILER_EXCLUDE_PATHS, compiled to Option<Arc<GlobSet>> on ProfilerConfig.
  • Refactor: extract config::compile_glob_csv(raw, label) shared verbatim by PHP_DENY_PATHS and PROFILER_EXCLUDE_PATHS so their glob semantics can't drift; removes php_deny's now-unused normalize_pattern/inline builder.
  • API: /config reports the profiler's exclude_paths (configured patterns) so an operator can confirm the exclusion compiled.
  • Docs: "5.5 Excluding paths from sampling" subsection + config-table row in en/ru/zh, plus a changelog entry.

Tests

9 new unit tests (parse semantics, sampling gate, explicit-trigger bypass, raw-path behavior, bare-vs-subtree). Full suite green; php_deny refactor verified against its existing test suite.

Config:
  - PROFILER_EXCLUDE_PATHS: comma-separated glob patterns whose matching request paths are kept out of PROFILER_SAMPLE_RATE sampling, so framework self-traffic (Symfony's /_profiler and /_wdt toolbar requests, Laravel Debugbar/Telescope) no longer pollutes captured profiles. Compiled into an Option<Arc<GlobSet>> on ProfilerConfig, parsed unconditionally so a malformed glob fails fast at startup. Exclusion gates the sample_rate branch only: an explicit trigger (x-oxphp-profile header, OXPROF cookie, __oxprof query) still profiles an excluded path. Matching runs on the raw request path at RequestReceived (before routing), so no percent-decoding or dot-segment normalization — only the glob syntax is shared with PHP_DENY_PATHS, not the matched input.

Refactor:
  - Extract config::compile_glob_csv(raw, label) — the split/trim/leading-slash-strip and literal_separator(true) GlobSet build shared verbatim by PHP_DENY_PATHS and PROFILER_EXCLUDE_PATHS, so their glob semantics cannot drift apart. php_deny routes through it; its now-unused normalize_pattern helper and inline builder are removed.

API:
  - /config reports the profiler's exclude_paths (configured patterns) next to enabled/sample_rate/auth_token_configured, so an operator can confirm the exclusion compiled.

Docs:
  - Add a "5.5 Excluding paths from sampling" subsection and config-table row to the en/ru/zh profiler guides, with the Symfony/Laravel recipe and a prominent note that exclusion affects automatic sampling only. Add a changelog entry under Unreleased.

Misc:
  - path_excluded uses unwrap_or instead of unwrap_or_else — uri.path() is a cheap borrow with nothing to defer.

9 tests (9 unit).
@diolektor diolektor force-pushed the feature/profiler-exclude-paths branch from 827ac87 to d24d157 Compare June 23, 2026 21:14
@diolektor diolektor merged commit 60e26da into main Jun 23, 2026
6 checks passed
@diolektor diolektor deleted the feature/profiler-exclude-paths branch June 23, 2026 21:16
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