refactor: report errors through utopia-php/span instead of utopia-php/logger - #9
Conversation
The image already runs PHP 8.5 (appwrite/base:1.1.1), and the lock was resolved with --ignore-platform-reqs against packages that need 8.4 (utopia-php/queue, utopia-php/pools, PHPUnit 13), so the ">=8.3.0" constraint no longer described what the code can run on. utopia-php/span 4.2, which the next commit adds for error reporting, also requires 8.4.
…/logger utopia-php/logger is being archived (appwrite/appwrite#13828) and the error handler was its only consumer here. Each request now opens a span; the error action sets the throwable on it with error.type, error.code, http.method and http.path (the old log tags), and finishes it once the response is sent. A shutdown hook finishes successful request spans. Exporters are registered at boot: a Stdout exporter prints server errors as one JSON line on stderr, replacing the Console::error lines, and when GEO_LOGGING_CONFIG holds a sentry://PROJECT_ID:KEY@HOST DSN, span's Sentry exporter reports them to Sentry with the same environment, release and server name the logger sent. Client errors are marked error.publish=false so, as before, only 5xx and code-0 errors leave the process. GEO_LOGGING_PROVIDER is removed: the DSN scheme already names the provider, and Sentry is the only exporter span ships. AppSignal, Raygun and LogOwl DSNs and the legacy "key;projectId" form now log a warning at boot and disable error reporting. Adds a unit suite (run in CI) that drives the error action and asserts on what a recording exporter receives.
…_header PHP 8.5 deprecates the implicit $http_response_header local, which made the E2E suite report two deprecations on every run. Use http_get_last_response_headers() instead.
🔵 Tier A · Mergeable after minor fixes
Replaces logger-based error reporting with request spans and stdout/Sentry exporters, publishing only server errors. Removes GEO_LOGGING_PROVIDER, raises the PHP requirement to 8.4, and updates E2E response-header handling. The final version retains only the E2E suite rather than the previously added unit coverage. Latest changes: The newest commits remove the unit-test script and coverage, the explicit PSR-18 dependency and injectable Sentry transport, and reuse of an injected HTTP instance's resource container.
Fix with agent prompt### Issue 1
src/Geo/Server/Server.php:36
**Retain coverage for error exporter delivery and filtering**
With the unit tests removed, no remaining test checks that server errors reach the configured exporters or that client errors are suppressed; `tests/E2E/GeoTest.php` only checks HTTP responses. Please retain automated coverage for this reporting contract so a broken sampler or missing error attachment cannot pass the suite.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.📂 Walkthrough · 6
Reviewed the commits since |
The error action tests used an exporter that sampled everything, so they stayed green if the production filter was removed. ServerTest boots Server with an FPM adapter and a recording PSR-18 client for span's Sentry exporter, runs requests through the real hooks inside a coroutine, and asserts a 500 is delivered while a 401, a 404 and a 200 are not. Server takes an optional client (passed to the Sentry exporter) and reuses the injected Http's resources container, so the test drives the same boot path. Stdout and Sentry now share one sampler; Stdout writes to the STDERR constant, which a test cannot capture in-process, so the Sentry delivery stands in for both.
The refactor commit picked up .phpunit.result.cache from a local unit-test run. It is per-machine state, so remove it and ignore it.
Keep this PR to the logger-to-span move and the E2E suite the repository already runs. The unit tests needed two seams in Server that production never uses (an injectable PSR-18 client for the Sentry exporter and reusing a passed Http's resources), so those and the direct psr/http-client requirement go with them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
|
||
| Http::setMode(System::getEnv('GEO_ENV', Http::MODE_TYPE_PRODUCTION)); | ||
|
|
||
| $this->initSpan(); |
There was a problem hiding this comment.
Retain coverage for error exporter delivery and filtering
With the unit tests removed, no remaining test checks that server errors reach the configured exporters or that client errors are suppressed; tests/E2E/GeoTest.php only checks HTTP responses. Please retain automated coverage for this reporting contract so a broken sampler or missing error attachment cannot pass the suite.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Geo/Server/Server.php
Line: 36
Comment:
**Retain coverage for error exporter delivery and filtering**
With the unit tests removed, no remaining test checks that server errors reach the configured exporters or that client errors are suppressed; `tests/E2E/GeoTest.php` only checks HTTP responses. Please retain automated coverage for this reporting contract so a broken sampler or missing error attachment cannot pass the suite.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.🟡 Minor · testing · Reply if this doesn't apply.
What changed
utopia-php/loggerand addedutopia-php/span4.2.0. The error action no longer builds aUtopia\Logger\Log. It sets the throwable on the current request span and adds the attributes the old log carried as tags:error.type,error.code,http.methodandhttp.path. It finishes the span after the response is sent.onRequesthook opens anhttp.requestspan, and a*shutdown hook finishes it when the request succeeds. Storage isStorage\Coroutine.Server::initSpan():Stdoutprints server errors as one JSON line on stderr. This replaces the oldConsole::errorlines.Sentryis added whenGEO_LOGGING_CONFIGholds asentry://PROJECT_ID:KEY@HOSTDSN, parsed withUtopia\DSN\DSN. It keeps the environment (production/staging fromGEO_ENV), release (GEO_VERSION) and server name (hostname) the logger sent.error.publish=false, so only 5xx and code-0 errors are printed or sent to Sentry. That matches the old behaviour.build:commit:composer.jsonnow requires PHP>=8.4instead of>=8.3.0. The Docker image (appwrite/base:1.1.1) already runs PHP 8.5.4, and the lock already contained packages that need 8.4 (utopia-php/queue,utopia-php/pools, PHPUnit 13). span 4.2 needs 8.4 as well. No Dockerfile change.test:commit: the E2E base now useshttp_get_last_response_headers(). This removes the two PHP 8.5 deprecations the suite reported on every run.Behaviour changes
GEO_LOGGING_PROVIDERis removed. The DSN scheme already names the provider. It was dropped from.envanddocker-compose.yml.key;projectIdform that went withGEO_LOGGING_PROVIDER, now printInvalid GEO_LOGGING_CONFIG, error reporting is disabled: ...at boot and report nothing. No provider is configured in this repo (.envhas both variables empty), and theappwrite-geodeployment inapplication-configurationsets onlyGEO_SECRET. So no deployed environment loses reporting today.httpErroraction shows up as thehttp.requesttransaction.[Error] ...lines.Validation
No unit suite: this PR keeps to the move and the E2E suite the repository already runs.
composer lint:{"result":"pass"}composer check(PHPStan level 8):[OK] No errorsdocker compose up -d --build geo, then the E2E suite in thetestscontainer): E2EOK (9 tests, 23 assertions). CI runs the same E2E suite on this PR.GEO_DBIP_PATH=/missing.mmdbandGEO_LOGGING_CONFIG=sentry://123:publickey@sentry.invalid:"level":"error","error.publish":true,"error.type":"Exception","error.code":0,"http.path":"/v1/ips/:ip") and one Sentry export attempt (Sentry exporter: Could not resolve host: sentry.invalid).GEO_LOGGING_CONFIG=raygun://key: printedInvalid GEO_LOGGING_CONFIG, error reporting is disabled: Only the sentry:// scheme is supported, and the server still started.Part of appwrite/appwrite#13828