-
Notifications
You must be signed in to change notification settings - Fork 166
Description
Describe the bug
Please provide a clear and concise description of what the bug is.
The default PHP-FPM configuration provided by the Google Cloud PHP buildpack (used in App Engine Standard and Cloud Run) sets log_limit
to its PHP default of 1024 characters. This causes structured JSON logs written to stdout
or stderr
(e.g., via file_put_contents('php://stderr', $json_string . PHP_EOL);
) to be split by PHP-FPM if the single JSON line exceeds 1024 characters.
This premature splitting:
- Prevents effective structured logging for PHP applications for any log messages slightly longer than 1KB.
- Causes the intended single JSON entry to be ingested as multiple, partial
textPayload
entries in Cloud Logging, rendering the structured data unsearchable and corrupt. - Places PHP at a disadvantage compared to other languages on the same platform (e.g., Go), which can successfully log single lines up to ~100KB to
stdout
/stderr
and have them ingested correctly asjsonPayload
. - Currently, there appears to be no straightforward or documented mechanism within App Engine Standard to allow users to override this specific
php-fpm.conf
log_limit
setting. Our attempts to provide a custom FPM pool configuration file in the workspace were not picked up by the runtime.
The PHP-FPM log_limit
directive was introduced in PHP 7.3.0 (see PHP Bug #69031 and PHP Manual on FPM Configuration) specifically to handle long log lines. Setting this log_limit
to a more practical default value within the buildpack would alleviate the observed log splitting problem and would likely be very useful for everyone using this PHP runtime for structured logging via stdout
/stderr
.
Additional context
How are you using GCP buildpacks?
-
pack
and thegcr.io/buildpacks/builder
- Cloud Functions
- Cloud Run
- Cloud Build
- App Engine Standard
- App Engine Flex
- Firebase App Hosting
(We primarily tested and confirmed this behavior on App Engine Standard with PHP 8.3. The same buildpack philosophy applies to Cloud Run PHP services.)
Did this used to work?
(Yes/No)
No, for stdout
/stderr
logging of lines exceeding PHP-FPM's default 1024-character log_limit
, this likely never worked as currently expected.
Previously, with PHP versions < 8.1 on App Engine, we successfully ingested structured logs by writing them to files in /var/log/*.log
. This method handled larger log entries correctly. However, this file-based logging approach has since been deprecated in favour of writing logs to stdout
/stderr
.
The current issue with stdout
/stderr
(specifically the ~1KB line splitting due to php-fpm
's default log_limit
) has therefore likely always been present for stdout
/stderr
logging. Our recent adoption of the recommended stdout
/stderr
logging pattern for structured logs has surfaced this underlying limitation in the default PHP-FPM configuration provided by the buildpack.
What language is your project primarily written in?
(Python/Java/Node.js/Go/etc.)
PHP (specifically tested with PHP 8.3)
Steps To Reproduce
Steps to reproduce the behavior:
- Deploy a PHP application to App Engine Standard using the standard PHP 8.3 runtime (or a Cloud Run service with the corresponding Google Cloud PHP buildpack).
- In a PHP script, generate a valid, single-line JSON string that is longer than 1024 characters (e.g., 2KB).
- Log this single-line JSON string to
stderr
, followed by a single newline character. Example:$data = ['message' => 'This is a test.', 'padding' => str_repeat('A', 2000)]; $json_string = json_encode($data); // This is a single line file_put_contents('php://stderr', $json_string . PHP_EOL);
- Observe the logs for this application in Google Cloud Logging.
(We can provide our detailed PoC scripts – previously attached aslog-debug.zip
in our Google Cloud Support ticket [Your Support Ticket ID, if you wish to reference it, otherwise omit] – which incrementally test various sizes).
Expected behavior
A clear and concise description of what you expected to happen.
- The single-line JSON string, up to a reasonable platform-supported limit for
stdout
/stderr
ingestion (e.g., the ~100KB observed with Go applications on the same platform, or ideally closer to the 256KB Cloud LoggingLogEntry
limit), should be ingested as a singlejsonPayload
entry in Cloud Logging. - The default
php-fpm
log_limit
in the Google Cloud PHP buildpack should be set to a much higher value (e.g., 102400 for 100KB, or 262144 for 256KB). - Alternatively, a clear and simple mechanism should be provided and documented for users to override
php-fpm
pool configurations likelog_limit
(andlog_buffering
) for their PHP applications on App Engine Standard and Cloud Run (buildpack-based), viaserve
... ?
Actual behavior
What actually happened?
- Any single-line JSON string logged to
stderr
from PHP that exceeds 1024 characters is split by PHP-FPM into multiple log entries. - These fragments appear as multiple
textPayload
lines in Cloud Logging, breaking the original JSON structure. This makes the structured log unusable for querying or analysis within Cloud Logging. - Inspection of the runtime
php-fpm.conf
(e.g., at/tmp/serve-php/php-fpm.conf
on App Engine Standard for PHP 8.3) confirmscatch_workers_output = yes
is active and does not show any user-override forlog_limit
, implying it uses the default 1024. An excerpt from the observed runtimephp-fpm.conf
:; Send errors to stderr. error_log = /proc/self/fd/2 ; ... catch_workers_output = yes decorate_workers_output = no ; log_limit is not set, so defaults to 1024 ; log_buffering is not set, so defaults to yes
(We will attach or link to our PoC scripts (log-debug.zip
) which demonstrate this behavior and this also includes a script to dump runtime configuration files from /tmp
for inspection.)