Notice 조건과 원격 로그 필터 보강

This commit is contained in:
seo
2026-07-26 01:36:07 +09:00
parent 58a81420d1
commit a42b6d7df7
5 changed files with 191 additions and 10 deletions
+80 -5
View File
@@ -2712,7 +2712,78 @@ function notice_rolling_baseline(array $history, float $temp, float $rpm, float
];
}
function fan_spike_analysis(array $history, array $fan, array $system, array $processes = []): array
function system_notice_extra_reasons(array $system, array $networkHistory): array
{
$reasons = [];
if ((bool)setting_value('notice.low_voltage_repeated') && !empty($system['low_voltage']['repeated'])) {
$count = (int)($system['low_voltage']['recent_event_count'] ?? 0);
$reasons[] = 'LOW VOLTAGE repeated ' . $count . 'x';
}
if ((bool)setting_value('notice.throttling_repeated') && !empty($system['throttling']['repeated'])) {
$count = (int)($system['throttling']['recent_event_count'] ?? 0);
$reasons[] = 'THROTTLING repeated ' . $count . 'x';
}
$diskThreshold = (float)setting_value('notice.disk_percent_threshold');
$diskPercent = (float)($system['disk']['percent'] ?? 0);
if ($diskThreshold > 0 && $diskPercent >= $diskThreshold) {
$reasons[] = 'DISK ' . round($diskPercent, 1) . '%';
}
$networkWindow = max(60, (int)setting_value('notice.network_quality_window_seconds'));
$errorThreshold = (float)setting_value('notice.network_error_threshold');
$dropThreshold = (float)setting_value('notice.network_drop_threshold');
if (($errorThreshold > 0 || $dropThreshold > 0) && $networkHistory !== []) {
$cutoff = time() - $networkWindow;
$totals = [];
$lastSeenAt = [];
foreach ($networkHistory as $row) {
$recordedAt = strtotime((string)($row['time'] ?? '')) ?: 0;
if ($recordedAt < $cutoff) {
continue;
}
$iface = (string)($row['iface'] ?? '');
if ($iface === '') {
continue;
}
$totals[$iface] ??= [
'rx_errors' => 0.0,
'tx_errors' => 0.0,
'rx_dropped' => 0.0,
'tx_dropped' => 0.0,
];
$seconds = 1.0;
if (isset($lastSeenAt[$iface])) {
$seconds = (float)max(1, min(60, $recordedAt - $lastSeenAt[$iface]));
}
$lastSeenAt[$iface] = $recordedAt;
$totals[$iface]['rx_errors'] += max(0.0, (float)($row['rx_errors_per_sec'] ?? 0)) * $seconds;
$totals[$iface]['tx_errors'] += max(0.0, (float)($row['tx_errors_per_sec'] ?? 0)) * $seconds;
$totals[$iface]['rx_dropped'] += max(0.0, (float)($row['rx_dropped_per_sec'] ?? 0)) * $seconds;
$totals[$iface]['tx_dropped'] += max(0.0, (float)($row['tx_dropped_per_sec'] ?? 0)) * $seconds;
}
foreach ($totals as $iface => $total) {
$errors = (int)round($total['rx_errors'] + $total['tx_errors']);
$drops = (int)round($total['rx_dropped'] + $total['tx_dropped']);
if ($errorThreshold > 0 && $errors >= $errorThreshold) {
$reasons[] = 'NET ' . $iface . ' errors +' . $errors;
}
if ($dropThreshold > 0 && $drops >= $dropThreshold) {
$reasons[] = 'NET ' . $iface . ' drops +' . $drops;
}
}
}
return $reasons;
}
function fan_spike_analysis(array $history, array $fan, array $system, array $processes = [], array $networkHistory = []): array
{
$rpm = (float)($fan['rpm'] ?? 0);
$pwm = (float)($fan['pwm'] ?? 0);
@@ -2788,8 +2859,11 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
$recoverRpmThreshold = (float)setting_value('notice.recover_rpm_delta');
$recoverTempThreshold = (float)setting_value('notice.recover_temp_delta');
if ($rpmExpected && abs($rpmDelta) >= $rpmThreshold) $reasons[] = 'RPM ' . signed_delta_text($rpmDelta);
if (abs($tempDelta) >= $tempThreshold) $reasons[] = 'TEMP ' . signed_delta_text($tempDelta, 'C');
$fanReasons = [];
if ($rpmExpected && abs($rpmDelta) >= $rpmThreshold) $fanReasons[] = 'RPM ' . signed_delta_text($rpmDelta);
if (abs($tempDelta) >= $tempThreshold) $fanReasons[] = 'TEMP ' . signed_delta_text($tempDelta, 'C');
$extraReasons = system_notice_extra_reasons($system, $networkHistory);
$reasons = array_values(array_merge($fanReasons, $extraReasons));
$alertStarted = false;
@@ -2812,8 +2886,9 @@ function fan_spike_analysis(array $history, array $fan, array $system, array $pr
save_system_notice_state('normal', $rollingBaseline['temp'], $rollingBaseline['rpm'], $rollingBaseline['pwm']);
}
} else {
$recovered = (abs($rpmDelta) <= $recoverRpmThreshold && abs($tempDelta) <= $recoverTempThreshold)
$fanRecovered = (abs($rpmDelta) <= $recoverRpmThreshold && abs($tempDelta) <= $recoverTempThreshold)
|| (abs($rollingRpmDelta) <= $recoverRpmThreshold && abs($rollingTempDelta) <= $recoverTempThreshold);
$recovered = $reasons === [] || ($extraReasons === [] && $fanRecovered);
if ($recovered || $reasons === []) {
$currentState = 'normal';
save_system_notice_state('normal', $rollingBaseline['temp'], $rollingBaseline['rpm'], $rollingBaseline['pwm']);
@@ -4741,11 +4816,11 @@ function collect_snapshot(bool $applyFan = true): array
}
$processes = process_resource_data((int)setting_value('display.process_limit'));
$fanSpike = fan_spike_analysis($history, $fan, $system, $processes);
$network = network_info();
add_network_usage_log($network);
$networkHistory = network_usage_history(1000);
$networkQualityTotals = network_quality_totals();
$fanSpike = fan_spike_analysis($history, $fan, $system, $processes, $networkHistory);
$shouldLogNotice = !empty($fanSpike['alert_started'])
|| (!empty($fanSpike['active']) && (bool)setting_value('notice.log_during_alert'));