Help needed: No output from php://stdout in frankenphp log
Hi,
I have a simple app with PHP 8.3/Laravel/Octane which I want to put in container. I use Laravel sample logging config 'single':
'single' => [
'driver' => 'single',
'path' => 'php://stdout',
'level' => env('LOG_LEVEL', 'debug'),
'replace_placeholders' => true,
],
Starting this app (without container) with:
php artisan octane:frankenphp --log-level=debug
produces caddy access log, but no application logging is shown.
If I set path to 'php://stderr' - it works as expected. Of course it works as well if I log to a file.
Is there some configuration I am missing to emit application log on stdout to caddy/frankephp logger?
When logging to stdout, don't you have to use a configuration like this?
'stdout' => [
'driver' => 'monolog',
'level' => env('LOG_LEVEL', 'debug'),
'handler' => StreamHandler::class,
'formatter' => env('LOG_STDERR_FORMATTER'),
'with' => [
'stream' => 'php://stdout',
],
'processors' => [PsrLogMessageProcessor::class],
],
It's because laravel octane runs frankenphp as a sub process and then forwards the output.
I just run it directly with a custom caddyfile. Much less hassle.
# in the dockerimage.
CMD ["frankenphp", "run", "-c", "/etc/caddy/Caddyfile"]
And a custom bootstrap stub in public/frankenphp-worker.php
<?php
// These env vars are required for the octane bootstrap file to work.
$_SERVER['MAX_REQUESTS'] = $_SERVER['LARAVEL_OCTANE_MAX_WORKER_REQUESTS'];
$_SERVER['REQUEST_MAX_EXECUTION_TIME'] = $_SERVER['LARAVEL_OCTANE_MAX_EXECUTION_TIME'];
$_SERVER['APP_BASE_PATH'] = dirname(__DIR__);
$_SERVER['APP_PUBLIC_PATH'] = $_SERVER['APP_BASE_PATH'].'/public';
require dirname(__DIR__).'/vendor/laravel/octane/bin/frankenphp-worker.php';
Looks great, could you please share your Caddy file. Thanks.
07.12.2024 15:15:49 Calvin Alkan @.***>:
It's because laravel octane runs frankenphp as a sub process and then forwards the output.
I just run it directly with a custom caddyfile. Much less hassle.
in the dockerimage.
CMD ["frankenphp", "run", "-c", "/etc/caddy/Caddyfile"]
And a custom bootstrap stub in public/frankenphp-worker.php
{
# The server only runs on port 80 behind a reverse proxy.
# We don't https.
auto_https off
# No reason to add certificates in local dev.
# Caddy only runs in docker.
skip_install_trust
log {
level {$CADDY_GLOBAL_LOG_LEVEL}
output stderr
}
servers {
metrics
}
frankenphp {
{$FRANKENPHP_NUM_PHP_THREADS_OPTION}
worker {
file public/frankenphp-worker.php
{$CADDY_FRANKENPHP_WORKER_WATCH_OPTIONS}
{$FRANKENPHP_NUM_WORKERS_OPTION}
}
}
}
http://:80 {
log {
level {$CADDY_SERVER_LOG_LEVEL}
output stderr
}
handle /app-ping {
respond "app pong" 200
}
# Security headers
header {
# Allow Livewire to work while keeping external requests blocked
# There is https://github.com/spatie/laravel-csp to further secure this.
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"
# Prevent MIME type sniffing
X-Content-Type-Options "nosniff"
# Prevent iframe embedding
X-Frame-Options "DENY"
# Force HTTPS for 2 years, including subdomains
Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
# Send full URL for same-origin, only origin for HTTPS cross-origin, nothing for HTTP
Referrer-Policy "strict-origin-when-cross-origin"
}
@immutable_assets {
path /build/* /vendor/*
}
header @immutable_assets Cache-Control "public, max-age=31536000, immutable"
route {
root public
# Perform compression here, so that we need to send less data to the reverse proxy.
encode zstd br gzip
php_server {
index frankenphp-worker.php
# Required for the public/storage/ directory...
resolve_root_symlink
}
}
}
Had the same issue a while ago, logging to stderr instead of stdout solved the issue for us. As log levels are set explicitly anyhow, this does not affect logging services.