원격 로그 상태 진단 추가
This commit is contained in:
+136
@@ -121,6 +121,141 @@ function dmesg_log(): array
|
||||
];
|
||||
}
|
||||
|
||||
function command_first_line(array $cmd, bool $root = false, int $timeout = 3): string
|
||||
{
|
||||
$result = sh($cmd, $root, $timeout);
|
||||
$lines = array_values(array_filter(
|
||||
preg_split('/\R/', trim((string)$result['out'])) ?: [],
|
||||
static fn($line): bool => trim((string)$line) !== ''
|
||||
));
|
||||
|
||||
return (int)$result['code'] === 0 && $lines ? (string)$lines[0] : '';
|
||||
}
|
||||
|
||||
function remote_log_file_status(string $dir): array
|
||||
{
|
||||
$files = [];
|
||||
$totalBytes = 0;
|
||||
$newest = null;
|
||||
|
||||
foreach (glob(rtrim($dir, '/') . '/*.log') ?: [] as $path) {
|
||||
$size = filesize($path) ?: 0;
|
||||
$mtime = filemtime($path) ?: 0;
|
||||
$totalBytes += $size;
|
||||
|
||||
$row = [
|
||||
'name' => basename($path),
|
||||
'path' => $path,
|
||||
'size_bytes' => $size,
|
||||
'size' => bytes_human($size),
|
||||
'updated_at' => $mtime > 0 ? date('Y-m-d H:i:s', $mtime) : null,
|
||||
'age_seconds' => $mtime > 0 ? max(0, time() - $mtime) : null,
|
||||
];
|
||||
$files[] = $row;
|
||||
|
||||
if ($newest === null || (int)$row['age_seconds'] < (int)($newest['age_seconds'] ?? PHP_INT_MAX)) {
|
||||
$newest = $row;
|
||||
}
|
||||
}
|
||||
|
||||
usort($files, static fn($a, $b): int => (int)($a['age_seconds'] ?? PHP_INT_MAX) <=> (int)($b['age_seconds'] ?? PHP_INT_MAX));
|
||||
|
||||
return [
|
||||
'path' => $dir,
|
||||
'available' => is_dir($dir),
|
||||
'file_count' => count($files),
|
||||
'total_bytes' => $totalBytes,
|
||||
'total_size' => bytes_human($totalBytes),
|
||||
'newest' => $newest,
|
||||
'files' => array_slice($files, 0, 5),
|
||||
];
|
||||
}
|
||||
|
||||
function remote_log_queue_status(): array
|
||||
{
|
||||
$result = sh([
|
||||
'/usr/bin/find',
|
||||
'/var/spool/rsyslog',
|
||||
'-maxdepth',
|
||||
'1',
|
||||
'-name',
|
||||
'control_synology_fwd*',
|
||||
'-printf',
|
||||
'%s\n',
|
||||
], true, 3);
|
||||
|
||||
if ((int)$result['code'] !== 0) {
|
||||
return [
|
||||
'available' => false,
|
||||
'file_count' => null,
|
||||
'total_bytes' => null,
|
||||
'total_size' => '-',
|
||||
];
|
||||
}
|
||||
|
||||
$sizes = array_values(array_filter(
|
||||
array_map('trim', preg_split('/\R/', trim((string)$result['out'])) ?: []),
|
||||
static fn($line): bool => $line !== ''
|
||||
));
|
||||
$total = array_sum(array_map('intval', $sizes));
|
||||
|
||||
return [
|
||||
'available' => true,
|
||||
'file_count' => count($sizes),
|
||||
'total_bytes' => $total,
|
||||
'total_size' => bytes_human($total),
|
||||
];
|
||||
}
|
||||
|
||||
function remote_log_status(): array
|
||||
{
|
||||
$journalDir = '/var/log/journal';
|
||||
$journalDisk = command_first_line(['/usr/bin/journalctl', '--disk-usage', '--no-pager'], false, 3);
|
||||
$journalBoots = command_first_line(['/usr/bin/bash', '-lc', 'journalctl --list-boots --no-pager 2>/dev/null | wc -l'], false, 3);
|
||||
$rsyslogActive = command_first_line(['/usr/bin/systemctl', 'is-active', 'rsyslog'], false, 3) ?: 'unknown';
|
||||
$rsyslogEnabled = command_first_line(['/usr/bin/systemctl', 'is-enabled', 'rsyslog'], false, 3) ?: 'unknown';
|
||||
$pstoreActive = command_first_line(['/usr/bin/systemctl', 'is-active', 'control-pstore-collect.service'], false, 3) ?: 'inactive';
|
||||
$listener = sh(['/usr/bin/ss', '-lnt', 'sport', '=', ':6514'], false, 3);
|
||||
$listenerOk = (int)$listener['code'] === 0 && str_contains((string)$listener['out'], ':6514');
|
||||
$remoteFiles = remote_log_file_status('/var/log/remote/synology');
|
||||
$queue = remote_log_queue_status();
|
||||
$savedCrashFiles = glob('/var/log/pstore/*') ?: [];
|
||||
$pstoreFiles = glob('/sys/fs/pstore/*') ?: [];
|
||||
|
||||
return [
|
||||
'raspberry_to_synology' => [
|
||||
'target' => 'chaegeon.com:6514',
|
||||
'transport' => 'TCP/TLS',
|
||||
'rsyslog_active' => $rsyslogActive,
|
||||
'rsyslog_enabled' => $rsyslogEnabled,
|
||||
'queue' => $queue,
|
||||
'ok' => $rsyslogActive === 'active',
|
||||
],
|
||||
'synology_to_raspberry' => [
|
||||
'listen_port' => 6514,
|
||||
'transport' => 'TCP/TLS',
|
||||
'listener' => $listenerOk,
|
||||
'logs' => $remoteFiles,
|
||||
'ok' => $listenerOk && $remoteFiles['file_count'] > 0,
|
||||
],
|
||||
'journal' => [
|
||||
'path' => $journalDir,
|
||||
'persistent' => is_dir($journalDir),
|
||||
'disk_usage' => $journalDisk ?: '-',
|
||||
'boot_count' => is_numeric(trim($journalBoots)) ? (int)trim($journalBoots) : null,
|
||||
'ok' => is_dir($journalDir),
|
||||
],
|
||||
'pstore' => [
|
||||
'mounted' => is_dir('/sys/fs/pstore'),
|
||||
'collector_active' => $pstoreActive,
|
||||
'pending_files' => count($pstoreFiles),
|
||||
'saved_files' => count($savedCrashFiles),
|
||||
'saved_path' => '/var/log/pstore',
|
||||
'ok' => is_dir('/sys/fs/pstore'),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
function power_event_state_read(string $eventKey): array
|
||||
{
|
||||
$state = [
|
||||
@@ -4123,6 +4258,7 @@ function collect_snapshot(bool $applyFan = true): array
|
||||
'history' => $history,
|
||||
'processes' => $processes,
|
||||
'custom_services' => custom_systemd_services(),
|
||||
'remote_logs' => remote_log_status(),
|
||||
'touch_display' => touch_display_status(),
|
||||
'fan_spike' => $fanSpike,
|
||||
'fan_spike_history' => fan_spike_history((int)setting_value('display.fan_notice_history_limit')),
|
||||
|
||||
Reference in New Issue
Block a user