Skip to content

Conversation

PROFeNoM
Copy link
Contributor

@PROFeNoM PROFeNoM commented Oct 1, 2025

Description

Reviewer checklist

  • Test coverage seems ok.
  • Appropriate labels assigned.

@PROFeNoM PROFeNoM self-assigned this Oct 1, 2025
@codecov-commenter
Copy link

codecov-commenter commented Oct 1, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.85%. Comparing base (bc34608) to head (fe999f0).
⚠️ Report is 10 commits behind head on master.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #3436      +/-   ##
==========================================
- Coverage   61.87%   61.85%   -0.02%     
==========================================
  Files         141      141              
  Lines       12481    12481              
  Branches     1630     1630              
==========================================
- Hits         7722     7720       -2     
- Misses       4038     4041       +3     
+ Partials      721      720       -1     

see 1 file with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bc34608...fe999f0. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@pr-commenter
Copy link

pr-commenter bot commented Oct 1, 2025

Benchmarks [ tracer ]

Benchmark execution time: 2025-10-01 08:39:04

Comparing candidate commit a5638f5 in PR branch alex/feat/process-tags with baseline commit bc34608 in branch master.

Found 1 performance improvements and 6 performance regressions! Performance is the same for 187 metrics, 0 unstable metrics.

scenario:ComposerTelemetryBench/benchTelemetryParsing-opcache

  • 🟥 execution_time [+373.276ns; +1426.724ns] or [+3.010%; +11.506%]

scenario:MessagePackSerializationBench/benchMessagePackSerialization

  • 🟥 execution_time [+4.985µs; +5.895µs] or [+4.447%; +5.258%]

scenario:SamplingRuleMatchingBench/benchRegexMatching1

  • 🟥 execution_time [+118.484ns; +179.116ns] or [+10.257%; +15.507%]

scenario:SamplingRuleMatchingBench/benchRegexMatching2

  • 🟥 execution_time [+94.752ns; +153.448ns] or [+8.114%; +13.141%]

scenario:SamplingRuleMatchingBench/benchRegexMatching3

  • 🟥 execution_time [+101.349ns; +166.851ns] or [+8.740%; +14.389%]

scenario:SamplingRuleMatchingBench/benchRegexMatching4

  • 🟥 execution_time [+90.491ns; +159.709ns] or [+7.747%; +13.673%]

scenario:TraceSerializationBench/benchSerializeTrace

  • 🟩 execution_time [-29.739µs; -18.961µs] or [-6.667%; -4.251%]

*ptr = '\0';

// Create a persistent zend_string
process_tags.serialized = zend_string_init(buffer, total_len, 1);
Copy link
Collaborator

@bwoebi bwoebi Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The better way would be

    process_tags.serialized = zend_string_alloc(total_len, 1);
    char *ptr = ZSTR_VAL(process_tags.serialized);

rather than creating a temporary buffer, to copy and free it; right away allocate the zend_string and manipulate its contents.

Comment on lines 188 to 189
const process_tag_entry_t *tag_a = (const process_tag_entry_t *)a;
const process_tag_entry_t *tag_b = (const process_tag_entry_t *)b;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const process_tag_entry_t *tag_a = (const process_tag_entry_t *)a;
const process_tag_entry_t *tag_b = (const process_tag_entry_t *)b;
const process_tag_entry_t *tag_a = a;
const process_tag_entry_t *tag_b = b;

Needing an explicit cast of void pointers is so C++ :-D

Comment on lines 262 to 284
// Try to get executable path
#ifdef _WIN32
char exe_path[PATH_MAX];
DWORD len = GetModuleFileNameA(NULL, exe_path, PATH_MAX);
if (len > 0 && len < PATH_MAX) {
entrypoint_name = get_basename(exe_path);
entrypoint_basedir = get_dirname(exe_path);
}
#else
char exe_path[PATH_MAX];
ssize_t len = readlink("/proc/self/exe", exe_path, sizeof(exe_path) - 1);
if (len != -1) {
exe_path[len] = '\0';
entrypoint_name = get_basename(exe_path);
entrypoint_basedir = get_dirname(exe_path);
} else {
// Fallback: use argv[0] or executable_location if available
if (sapi_module.executable_location) {
entrypoint_name = get_basename(sapi_module.executable_location);
entrypoint_basedir = get_dirname(sapi_module.executable_location);
}
}
#endif
Copy link
Collaborator

@bwoebi bwoebi Oct 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not what we want to actually collect. We are never interested in /proc/self/exe, which always is the php (or webserver) executable.
For PHP specifically the entrypoint is the primary script executed, and actually not a process-global in non-CLI cases. ... which makes no sense for non-cli process tags, so they should be omitted then (???).
This one though, annoyingly, is not available at minit time (but at first_rinit, which is good enough).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are absolutely right. Changed it to use SG(request_info).path_translated for the actual script, moved everything to first_rinit() like you suggested, and ditched the MINIT hook entirely.

But then, I went down a rabbit hole on your 'makes no sense for non-CLI" comment. I looked a bit deeper at the Java Implementation and the Collected Tags Table, and they do collect process tags for web servers like Tomcat and JBoss: they get server.type (the vendor) and other metadata. So I figured PHP-FPM etc. is kind of similar - one pool usually serves one app, and the SAPI name is basically our version of server.type: tomcat.

So right now, it collects full entrypoint info for CLI (script name, basedir, etc.) but for web SAPIs it just gets server.type (the SAPI name) and entrypoint.workdir. No script name for web since different requests = different scripts, like you said.

My thinking was that most production PHP is not CLI, so excluding web would mean this only helps a small portion of workloads.

But if you think we should keep it CLI-only for simplicity, I'm happy to revert that part.
This is, anyway, something that will have to be perhaps discussed w/ the folks knowing more about that feature.

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