Skip to content

fix(telemetry): send the shared-hosting env signals the Worker expects - #1606

Merged
rumblefrog merged 1 commit into
mainfrom
claude/intelligent-faraday-ewdyzw
Oct 25, 2026
Merged

rumblefrog merged 1 commit into
mainfrom
claude/intelligent-faraday-ewdyzw

Conversation

@rumblefrog

Copy link
Copy Markdown
Member

Description

In the telemetry Analytics Engine data, env.sapi, env.memory_limit_mb, env.max_execution_time, env.disable_functions_count and all 12 new env.* bits are always null or 0. The Worker is fine: it validates and maps every one of these fields. The cause is on the panel side: it never sends them.

sbpp/cf-analytics#4 added these fields to schema-1. Its issue (sbpp/cf-analytics#3) listed a "lockstep panel-side work" item: a HostFingerprint helper, a re-vendored schema and a wider parity test. That work never landed, so Telemetry::collectEnv() still sends only the original five fields.

This PR:

  • Adds Sbpp\Telemetry\HostFingerprint, which computes the 16 fields as specified in cf-analytics#3.
    • Each probe is guarded against Throwable. If a host disables ini_get or posix_*, or open_basedir blocks the /usr/local/* checks, only that one field falls back. The ping still goes out.
    • Privacy: the open_basedir value, DOCUMENT_ROOT and the disable_functions list are reduced to a boolean or a count before they leave the class.
    • sapi_per_user follows the issue's leaning on its open question. The effective uid must own the panel files, be at least 1000 and not be nobody. Without POSIX it returns false.
    • docroot_user_home also matches /home2, /home3 and so on (cPanel's multi-disk layout).
  • Merges these fields into collectEnv() and adds them (with descriptions) to the vendored schema-1.lock.json.
  • Drops null values from the wire body. On hosts with no memory limit (memory_limit = -1), memory_limit_mb is null. The Worker's zod schema uses .optional(), which rejects an explicit null, so the whole ping would get a 400. collect() keeps the null so the parity test sees the same set of keys every time. send() strips it, the Worker treats the key as missing, and it stores a null double as intended.
  • Docs: adds the new fields to the user-facing "What's sent" list in updating/1-8-to-2-0.mdx, and updates ARCHITECTURE.md and AGENTS.md.

Separate pre-existing issue, not fixed here: make sync-telemetry-schema downloads cf-analytics/schema/1.lock.json. That file is the Worker's AE slot layout (blobs, doubles, bits), not a Draft-7 JSON Schema. Running the target would overwrite the panel's schema with a file Schema1 can't read. That's why the schema change here was made by hand.

Motivation and Context

Without these fields we can't tell shared-hosting installs from other installs, so the host_kind analysis in the cf-analytics README can't be run.

How Has This Been Tested?

  • ./sbpp.sh test --filter='HostFingerprint|Telemetry': 32 tests pass. That includes the parity test in both directions and the new HostFingerprintTest, which covers the memory_limit parser, the disable_functions count, the docroot regex, a check that the raw docroot never appears in the output, and withoutNulls.
  • Full ./sbpp.sh test: 1232 tests, 6 errors, all in PluginVersionResolveTest ($incBackup TypeError). The same 6 fail on main in the same environment.
  • ./sbpp.sh phpstan: no errors.
  • End to end: I dumped the panel's real wire body from the PHP 8.5 container, once as normal and once with -d memory_limit=-1. I ran both through the Worker's own validate() and mapDataPoint(). Both validate. env.sapi, memory_limit_mb (256, or null when unlimited), max_execution_time and disable_functions_count land in their slots, and all 12 env bits match the payload. I also confirmed that validate() rejects memory_limit_mb: null, which is why the null-stripping is needed.
  • docker build -f docker/Dockerfile.prod . (amd64 only, no qemu available) succeeds, and HostFingerprint::collect() runs inside the built image.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.

Generated by Claude Code

sbpp/cf-analytics#4 extended schema-1 with env.sapi, three env doubles
(memory_limit_mb, max_execution_time, disable_functions_count) and
twelve env bits, and called for a paired panel change. That change
never landed, so every ping arrived without them and the Analytics
Engine rows carried null / 0 in those slots for every install.

Add Sbpp\Telemetry\HostFingerprint, which computes the 16 fields per
cf-analytics#3 (each probe Throwable-guarded; open_basedir value,
DOCUMENT_ROOT and the disable_functions list reduced to a boolean or
count), and merge it into Telemetry::collectEnv(). Extend the vendored
JSON Schema and the parity test to match.

memory_limit_mb is null on unlimited hosts. The Worker's zod schema
rejects an explicit null (whole ping 400s), so send() now drops null
leaves and the Worker sees the key as absent, which it maps to a null
double as intended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bwe7AmJS69ccciKdc2PPQi
@rumblefrog
rumblefrog requested a review from a team October 25, 2026 16:51
@github-actions

Copy link
Copy Markdown

Thanks for the PR! This change touches web/** (the SourceBans++ web panel),
which is covered by the project's Contributor License Agreement.

To sign, comment exactly the following line on this PR:

I have read the CLA Document and I hereby sign the CLA

You only need to sign once — your signature applies to every future
web-panel PR you open against this repo. Plugin-only PRs
(game/addons/sourcemod/**) don't need a signature.

See CONTRIBUTING.md
for the rationale.


I have read the CLA Document and I hereby sign the CLA


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the CLA Assistant Lite bot.

@rumblefrog
rumblefrog merged commit b67c6cd into main Oct 25, 2026
5 of 6 checks passed
@rumblefrog
rumblefrog deleted the claude/intelligent-faraday-ewdyzw branch October 25, 2026 16:54
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 25, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants