원격 로그 상태 진단 추가

This commit is contained in:
seo
2026-07-25 19:08:05 +09:00
parent c2099c21f0
commit 10c00b3e57
4 changed files with 292 additions and 2 deletions
+136
View File
@@ -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')),