feat: enhance firewall log loading in Proxmox by implementing batch fetching, improved error handling, and support for multiple response formats
This commit is contained in:
@@ -1093,23 +1093,113 @@ class Firewall extends Component
|
||||
|
||||
public function loadFirewallLogs(): void
|
||||
{
|
||||
$this->logError = '';
|
||||
|
||||
try {
|
||||
$response = $this->firewallRequest(
|
||||
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/log',
|
||||
'get',
|
||||
['limit' => $this->logLimit]
|
||||
);
|
||||
// Fetch logs in batches to handle large log sets
|
||||
$allRawLogs = [];
|
||||
$start = 0;
|
||||
$batchSize = 500;
|
||||
$maxLogs = $this->logLimit;
|
||||
|
||||
do {
|
||||
$response = $this->firewallRequest(
|
||||
'/nodes/' . $this->server->node->name . '/qemu/' . $this->server->vm_id . '/firewall/log',
|
||||
'get',
|
||||
[
|
||||
'limit' => $batchSize,
|
||||
'start' => $start
|
||||
]
|
||||
);
|
||||
|
||||
if ($response->successful()) {
|
||||
$rawLogs = $response->json()['data'] ?? [];
|
||||
$this->firewallLogs = $this->parseFirewallLogs($rawLogs);
|
||||
$this->logError = '';
|
||||
} else {
|
||||
$this->logError = 'Failed to load firewall logs';
|
||||
if (!$response->successful()) {
|
||||
$this->logError = 'Failed to fetch logs (HTTP ' . $response->status() . ')';
|
||||
Log::warning('Firewall log API request failed', [
|
||||
'status' => $response->status(),
|
||||
'server_id' => $this->server->id,
|
||||
'vm_id' => $this->server->vm_id,
|
||||
]);
|
||||
$this->firewallLogs = [];
|
||||
return;
|
||||
}
|
||||
|
||||
// Proxmox firewall log endpoint can return JSON or text/plain
|
||||
$body = $response->body();
|
||||
$batchRawLogs = [];
|
||||
|
||||
// Check content type
|
||||
$contentType = $response->header('Content-Type');
|
||||
$isJson = str_contains($contentType ?? '', 'json');
|
||||
|
||||
if ($isJson) {
|
||||
try {
|
||||
$jsonData = $response->json();
|
||||
|
||||
if (isset($jsonData['data'])) {
|
||||
if (is_array($jsonData['data'])) {
|
||||
foreach ($jsonData['data'] as $item) {
|
||||
if (is_array($item) && isset($item['t'])) {
|
||||
$batchRawLogs[] = $item['t'];
|
||||
} elseif (is_string($item)) {
|
||||
$batchRawLogs[] = $item;
|
||||
}
|
||||
}
|
||||
} elseif (is_string($jsonData['data'])) {
|
||||
$lines = preg_split('/\r\n|\r|\n/', $jsonData['data']);
|
||||
$batchRawLogs = array_filter($lines, fn($line) => !empty(trim($line)));
|
||||
}
|
||||
} elseif (is_array($jsonData)) {
|
||||
foreach ($jsonData as $item) {
|
||||
if (is_array($item) && isset($item['t'])) {
|
||||
$batchRawLogs[] = $item['t'];
|
||||
} elseif (is_string($item)) {
|
||||
$batchRawLogs[] = $item;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Failed to parse JSON response', ['error' => $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to text/plain format
|
||||
if (empty($batchRawLogs) && !empty($body)) {
|
||||
$lines = preg_split('/\r\n|\r|\n/', $body);
|
||||
$batchRawLogs = array_filter($lines, fn($line) => !empty(trim($line)));
|
||||
}
|
||||
|
||||
$batchRawLogs = array_values($batchRawLogs);
|
||||
$allRawLogs = array_merge($allRawLogs, $batchRawLogs);
|
||||
$fetchedCount = count($batchRawLogs);
|
||||
$start += $batchSize;
|
||||
|
||||
// Break if we got fewer logs than requested or reached limit
|
||||
if ($fetchedCount < $batchSize || count($allRawLogs) >= $maxLogs) {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
|
||||
// Limit to maxLogs
|
||||
if (count($allRawLogs) > $maxLogs) {
|
||||
$allRawLogs = array_slice($allRawLogs, 0, $maxLogs);
|
||||
}
|
||||
|
||||
Log::info('Firewall logs fetched from Proxmox API', [
|
||||
'raw_count' => count($allRawLogs),
|
||||
'first_3_logs' => array_slice($allRawLogs, 0, 3)
|
||||
]);
|
||||
|
||||
$this->firewallLogs = $this->parseFirewallLogs($allRawLogs);
|
||||
|
||||
Log::info('Firewall log parsing summary', [
|
||||
'total_raw_logs' => count($allRawLogs),
|
||||
'successfully_parsed' => count($this->firewallLogs),
|
||||
]);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
$this->logError = 'Failed to load logs: ' . $e->getMessage();
|
||||
Log::error('Firewall logs error: ' . $e->getMessage());
|
||||
$this->firewallLogs = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user