Give the PHP layer somewhere to record what it swallowed
This commit is contained in:
@@ -160,6 +160,56 @@ define('LOG_DIR', '/var/log/varaverk');
|
||||
define('CUSTOM_SCRIPTS_DIR', $_vv_cfg['CUSTOM_SCRIPTS_DIR'] ?? '/boot/config/plugins/user.scripts/Varaverk/Scripts');
|
||||
unset($_vv_cfg);
|
||||
|
||||
// ── Recording a failure this layer chose to survive ───────────────────────────────────────────
|
||||
// The bash half writes a log for every run. The PHP half had nowhere to write at all — no
|
||||
// error_log() call in 107 files — so an endpoint that caught an exception and carried on left no
|
||||
// trace anywhere. Five directory walks do exactly that, and an unreadable directory renders as a
|
||||
// legitimately empty result: the scheduler's script library shows "no scripts" whether you have
|
||||
// none or the tree could not be read.
|
||||
//
|
||||
// This is the smallest thing that fixes it. It does not change any response contract; it records
|
||||
// what was swallowed so the operator can find out why a page went empty.
|
||||
//
|
||||
// It lives in config.php because that is the one file every layer reaches — api/, include/ and
|
||||
// pages/ all load it, several of them without ever loading common.php.
|
||||
define('VV_PHP_LOG', LOG_DIR . '/php.log');
|
||||
define('VV_PHP_LOG_MAX', 262144); // 256KB. /var/log is tmpfs on Unraid — this is RAM, so a
|
||||
// repeating fault must not be able to grow without bound.
|
||||
|
||||
/**
|
||||
* Record a failure that was caught and survived. Never throws, never echoes, never affects the
|
||||
* response — a logger that can break a request is worse than no logger.
|
||||
*/
|
||||
function vv_log_error(string $where, string $message): void {
|
||||
try {
|
||||
if (!is_dir(LOG_DIR)) return;
|
||||
// Timestamps are local, matching every bash log — see "The clock this layer runs on".
|
||||
$line = date('Y-m-d H:i:s') . ' ' . $where . ' '
|
||||
. preg_replace('/\s+/', ' ', trim($message)) . "\n";
|
||||
|
||||
$size = @filesize(VV_PHP_LOG);
|
||||
if ($size !== false && $size > VV_PHP_LOG_MAX) {
|
||||
// Drop the older half rather than the whole file, so a fault that repeats every poll
|
||||
// still leaves recent context instead of a log that empties itself at random.
|
||||
$keep = @file_get_contents(VV_PHP_LOG, false, null, (int)(VV_PHP_LOG_MAX / 2));
|
||||
if ($keep !== false) {
|
||||
// Resume on a line boundary — slicing at a byte offset lands mid-line, and a
|
||||
// half-written first entry is worse than one fewer entry.
|
||||
$nl = strpos($keep, "\n");
|
||||
$keep = $nl === false ? '' : substr($keep, $nl + 1);
|
||||
@file_put_contents(VV_PHP_LOG, $keep, LOCK_EX);
|
||||
}
|
||||
}
|
||||
$isNew = !file_exists(VV_PHP_LOG);
|
||||
@file_put_contents(VV_PHP_LOG, $line, FILE_APPEND | LOCK_EX);
|
||||
// Do not inherit the ambient umask. php-fpm's is loose enough to create this 0666, and a
|
||||
// world-writable file under /var/log is the kind of small thing that is never noticed.
|
||||
if ($isNew) @chmod(VV_PHP_LOG, 0644);
|
||||
} catch (Throwable $_) {
|
||||
return; // Deliberately silent: this is the last place an error should propagate from.
|
||||
}
|
||||
}
|
||||
|
||||
define('VV_SETUP_STATE_FILE', STATE_DIR . '/varaverk_setup.db');
|
||||
|
||||
// ── The two install layouts ───────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user