Files
sva-e025532 c185d099d6 Add VIO FC Status monitoring page and enhance server inventory filtering
- Introduced `Storage/VIO.php` for monitoring VIO Fibre Channel status with client balancing checks and table sorting.
- Updated `/include/en.php` and `/include/fr.php` to include new translations for ServiceNow and VIO-related navigation elements.
- Improved SQL query and filtering logic in `/X/Inventory.php` to exclude VIO entries and add XenSam version data.
- Enhanced `/reports/heartbeat.php` with a new mechanism for handling server heartbeat status, allowing better granularity and readability.
2026-09-14 10:32:15 +02:00

200 lines
7.4 KiB
PHP

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Web Infra Reports IT</title>
<script src="/js/jquery-3.6.1.min.js"></script>
<link rel="stylesheet" href="/css/bootstrap.min.css">
<link rel="stylesheet" href="/css/bootstrap-icons/bootstrap-icons.css">
<script src="/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/css/bootstrap-table.min.css">
<script src="/js/bootstrap-table.min.js"></script>
<script src="/js/bootstrap-table-fr-FR.min.js"></script>
<script src="/js/tableExport.min.js"></script>
<script src="/js/bootstrap-table-export.min.js"></script>
</head>
<body class="bg-light text-dark">
<?php include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php"; ?>
<div class="container-fluid" id="content">
<div class="row flex-nowrap">
<div class="col-auto col-md-2 col-xl-2 px-sm-2 px-0 bg-dark vh-100 position-sticky top-0" style="flex: 0 0 230px;">
<?php include $_SERVER['DOCUMENT_ROOT'] . "/navbar.html"; ?>
</div>
<div class="col py-3">
<h2><span class="badge text-bg-secondary w-100" id="ERR">Veeam</span></h2>
<div class="container-fluid">
<table class='table table-bordered table-hover table-sm' id='t1'
data-toggle="table" data-search="true" data-show-columns="true"
data-show-export="true" data-sortable="true" data-height="620">
<thead>
<tr>
<th data-field='vm' data-sortable='true'><?php echo $w_VMs ;?></th>
<th data-field='LastRun' data-sortable='true'><?php echo $w_backuplu ;?></th>
<th data-field='Status' data-sortable='true'><?php echo $w_lastResult ;?></th>
<th data-field='LastGood' data-sortable='true'><?php echo $w_lastGoodBackup ;?></th>
<th data-field='Size' data-sortable='true'><?php echo $w_size ;?> (GB)</th>
<th data-field='Duration' data-sortable='true'>Duration</th>
<th data-field='Policy' data-sortable='true'><?php echo $w_policy ;?></th>
<th data-field='Error' data-sortable='true'>Message</th>
</tr>
</thead>
<tbody>
<?php
$conn = DB_INFRA();
$sql_vms = "SELECT name from cmdb_vms where CAST(lastinventory AS DATETIME) > DATEADD(DAY, -2, GETDATE()) ";
$rs_vms = odbc_exec($conn, $sql_vms);
$vmsae = [];
while ($row = odbc_fetch_array($rs_vms)){
$vmsae[] = $row['name'];
}
$conn = DB_INFRA();
$sql = "SELECT * FROM Veeam_Reporting";
$rs = odbc_exec($conn, $sql);
$total = 0; $er = 0; $outdated = 0; $excluded = 0; $success = 0; $war = 0;
$reportData = [];
// 1. Stockage et pré-calcul des poids de tri
while ($row = odbc_fetch_array($rs)) {
if(!in_array($row['ClientName'], $vmsae)) continue;
$total++;
$rowClass = "";
$sortWeight = 4; // Par défaut Success
$LastGoodStr = "NEVER";
// Calcul de l'ancienneté
$diffDays = 999;
if (!empty($row['LastSuccess']) && $row['LastSuccess'] != '1900-01-01') {
$date1 = date_create($row['LastSuccess']);
$diff = date_diff($date1, date_create(date("Y-m-d")));
$diffDays = (int)$diff->format("%R%a");
$LastGoodStr = date('Y-m-d H:i', strtotime($row['LastSuccess'])) . " (".$diffDays."J)";
if($diffDays > 365){$LastGoodStr = "NEVER";}
}
// Nouvelle logique de tri hiérarchique
if ($row['LastStatus'] == 'Failed' || $row['LastStatus'] == 'Unknown') {
$rowClass = "table-danger";
$sortWeight = 0;
$er++;
} elseif ($row['LastStatus'] == 'Warning') {
$rowClass = "table-warning";
$sortWeight = 1;
$war++;
} elseif ($diffDays >= 2) {
$rowClass = "table-info";
$sortWeight = 2;
$outdated++;
} elseif ($row['LastStatus'] == 'In Progress') {
$rowClass = "table-info";
$sortWeight = 3;
} else {
$rowClass = "table-success";
$sortWeight = 4;
$success++;
}
// On stocke les infos pour le tri PHP multiniveau
$reportData[] = [
'sort_weight' => $sortWeight,
'client_name' => $row['ClientName'],
'row_class' => $rowClass,
'last_run' => $row['LastRun'],
'last_status' => $row['LastStatus'],
'last_good' => $LastGoodStr,
'size' => $row['SizeGB'],
'duration' => $row['Duration'],
'policy_name' => $row['PolicyName'],
'error_message'=> $row['ErrorMessage']
];
}
// 2. Tri multiniveau en PHP : par poids d'abord, puis par nom de VM
usort($reportData, function($a, $b) {
if ($a['sort_weight'] === $b['sort_weight']) {
return strcasecmp($a['client_name'], $b['client_name']); // Tri alphabétique A-Z de la VM
}
return $a['sort_weight'] <=> $b['sort_weight']; // Tri ascendant du poids (0 à 4)
});
// 3. Rendu HTML des lignes triées
foreach ($reportData as $data) {
echo "<tr class='{$data['row_class']}'>";
echo "<td><b>{$data['client_name']}</b></td>";
echo "<td>" . date('Y-m-d H:i', strtotime($data['last_run'])) . "</td>";
// Conserve le data-sort pour permettre à l'utilisateur de retrier via bootstrap-table s'il clique sur la colonne
echo "<td data-sort='{$data['sort_weight']}'>{$data['last_status']}</td>";
echo "<td>{$data['last_good']}</td>";
echo "<td>{$data['size']}</td>";
echo "<td>{$data['duration']}</td>";
echo "<td>{$data['policy_name']}</td>";
echo "<td style='font-size: 0.8em;'><i>{$data['error_message']}</i></td>";
echo "</tr>";
}
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<?php
$success = $total - $er - $outdated - $excluded -$war;
$summary = "Veeam (<span class='text-light'>$success OK</span> - <span class='text-danger'>$er Error</span> - <span class='text-warning'>$war Warning</span> - <span class='text-info'>$outdated $w_outdated</span>)";
?>
</body>
<script>
$(function() {
// Initialisation unique avec tri par défaut basé sur l'ordre du DOM généré par le PHP
$('#t1').bootstrapTable({
sortName: 'Status',
sortOrder: 'asc'
});
document.getElementById("ERR").innerHTML = "<?php echo $summary; ?>";
});
</script>
<script src="/js/switch.js"></script>
</html>
<script>
function resizeTable() {
const table = document.getElementById('t1');
// position du tableau dans la page
const top = table.getBoundingClientRect().top;
// marge basse
const bottomMargin = 0;
// hauteur disponible
const height = window.innerHeight - top - bottomMargin;
$('#t1').bootstrapTable('refreshOptions', {
height: height
});
}
$(function () {
resizeTable();
$(window).on('resize', resizeTable);
});
</script>