- 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.
200 lines
7.4 KiB
PHP
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>
|