potential fix for logging on server
This commit is contained in:
112
lib/api_log.php
112
lib/api_log.php
@ -10,7 +10,8 @@
|
||||
* - web_change: POST/PUT/PATCH/DELETE from the management website (incl. translation labels)
|
||||
* - web_export: Website downloads (CSV/ZIP/JSON exports, translation bundle)
|
||||
*
|
||||
* Set QDB_API_LOG=0 to disable. Logs live under logs/api/ (gitignored).
|
||||
* Set QDB_API_LOG=0 to disable. Set QDB_API_LOG_DIR for a custom path.
|
||||
* Default directory is uploads/logs/api (writable by PHP alongside the database).
|
||||
*/
|
||||
|
||||
/** @var list<string> */
|
||||
@ -28,11 +29,98 @@ function qdb_api_log_enabled(): bool
|
||||
|
||||
function qdb_api_log_dir(): string
|
||||
{
|
||||
static $resolved = null;
|
||||
if ($resolved !== null) {
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
$custom = qdb_env_get('QDB_API_LOG_DIR');
|
||||
if ($custom !== null && $custom !== '') {
|
||||
return rtrim($custom, '/\\');
|
||||
$resolved = rtrim($custom, '/\\');
|
||||
return $resolved;
|
||||
}
|
||||
return dirname(__DIR__) . '/logs/api';
|
||||
|
||||
$root = dirname(__DIR__);
|
||||
foreach ([$root . '/uploads/logs/api', $root . '/logs/api'] as $candidate) {
|
||||
if (qdb_api_log_dir_is_usable($candidate)) {
|
||||
$resolved = $candidate;
|
||||
return $resolved;
|
||||
}
|
||||
}
|
||||
|
||||
$resolved = $root . '/uploads/logs/api';
|
||||
return $resolved;
|
||||
}
|
||||
|
||||
function qdb_api_log_dir_is_usable(string $dir): bool
|
||||
{
|
||||
if (is_dir($dir)) {
|
||||
return is_writable($dir);
|
||||
}
|
||||
$parent = dirname($dir);
|
||||
if (is_dir($parent) && is_writable($parent)) {
|
||||
return true;
|
||||
}
|
||||
if (@mkdir($dir, 0775, true)) {
|
||||
return is_writable($dir);
|
||||
}
|
||||
return is_dir($dir) && is_writable($dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagnostics for admin UI (permissions, path, enabled flag).
|
||||
*
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
function qdb_api_log_status(): array
|
||||
{
|
||||
$dir = qdb_api_log_dir();
|
||||
$enabled = qdb_api_log_enabled();
|
||||
$exists = is_dir($dir);
|
||||
$writable = false;
|
||||
$probeError = null;
|
||||
|
||||
if ($enabled) {
|
||||
if (!$exists) {
|
||||
if (!@mkdir($dir, 0775, true)) {
|
||||
$probeError = 'Cannot create directory: ' . $dir;
|
||||
}
|
||||
$exists = is_dir($dir);
|
||||
}
|
||||
if ($exists && !is_writable($dir)) {
|
||||
$probeError = 'Directory exists but is not writable by PHP: ' . $dir;
|
||||
} elseif ($exists) {
|
||||
$probe = $dir . '/.write_probe';
|
||||
if (@file_put_contents($probe, (string)time() . "\n", LOCK_EX) === false) {
|
||||
$probeError = 'Cannot write files in: ' . $dir;
|
||||
} else {
|
||||
$writable = true;
|
||||
@unlink($probe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$phpUser = null;
|
||||
if (function_exists('posix_geteuid') && function_exists('posix_getpwuid')) {
|
||||
$info = posix_getpwuid(posix_geteuid());
|
||||
if (is_array($info) && !empty($info['name'])) {
|
||||
$phpUser = (string)$info['name'];
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'enabled' => $enabled,
|
||||
'dir' => $dir,
|
||||
'exists' => $exists,
|
||||
'writable' => $writable,
|
||||
'error' => $probeError,
|
||||
'php_user' => $phpUser,
|
||||
'fix_hint' => $writable || !$enabled
|
||||
? null
|
||||
: 'On the server run: mkdir -p ' . $dir . ' && chown -R www-data:www-data '
|
||||
. dirname($dir) . ' && chmod -R 775 ' . dirname($dir)
|
||||
. ' (adjust www-data to your PHP user). Or set QDB_API_LOG_DIR in .env to a writable path.',
|
||||
];
|
||||
}
|
||||
|
||||
function qdb_api_log_max_bytes(): int
|
||||
@ -421,13 +509,24 @@ function qdb_api_log_change_scalar(mixed $v): string|int|float|bool|null
|
||||
function qdb_api_log_append_line(string $line): void
|
||||
{
|
||||
$dir = qdb_api_log_dir();
|
||||
if (!is_dir($dir) && !@mkdir($dir, 0755, true) && !is_dir($dir)) {
|
||||
throw new RuntimeException("Cannot create log directory: $dir");
|
||||
if (!is_dir($dir) && !@mkdir($dir, 0775, true) && !is_dir($dir)) {
|
||||
$err = error_get_last();
|
||||
throw new RuntimeException(
|
||||
'Cannot create log directory: ' . $dir
|
||||
. ($err ? ' (' . ($err['message'] ?? '') . ')' : '')
|
||||
);
|
||||
}
|
||||
if (!is_writable($dir)) {
|
||||
throw new RuntimeException('Log directory not writable: ' . $dir);
|
||||
}
|
||||
|
||||
$path = qdb_api_log_resolve_write_path($dir);
|
||||
if (@file_put_contents($path, $line, FILE_APPEND | LOCK_EX) === false) {
|
||||
throw new RuntimeException("Cannot write API log: $path");
|
||||
$err = error_get_last();
|
||||
throw new RuntimeException(
|
||||
'Cannot write API log: ' . $path
|
||||
. ($err ? ' (' . ($err['message'] ?? '') . ')' : '')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -507,6 +606,7 @@ function qdb_api_log_read_entries(string $date, string $activityFilter = '', int
|
||||
'files' => array_map('basename', $files),
|
||||
'truncated' => $truncated,
|
||||
'kinds' => QDB_API_LOG_ACTIVITIES,
|
||||
'logStatus' => qdb_api_log_status(),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user