247 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<html>
 | 
						|
<head>
 | 
						|
    <meta charset="UTF-8">
 | 
						|
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
						|
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						|
    <title>{{ titre }}</title>
 | 
						|
     <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
 | 
						|
    <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
 | 
						|
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.bundle.min.js" integrity="sha384-w76AqPfDkMBDXo30jS1Sgez6pr3x5MlQ1ZAGC+nuZB+EYdgRZgiwxhTBTkF7CXvN" crossorigin="anonymous"></script>
 | 
						|
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.css" integrity="sha512-/zs32ZEJh+/EO2N1b0PEdoA10JkdC3zJ8L5FTiQu82LR9S/rOQNfQN7U59U9BC12swNeRAz3HSzIL2vpp4fv3w==" crossorigin="anonymous" referrerpolicy="no-referrer"/>
 | 
						|
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
 | 
						|
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js" integrity="sha512-d9xgZrVZpmmQlfonhQUvTR7lMPtO7NkZMkA0ABN3PHCbKA5nqylQ/yWlFAyY6hYgdF1Qh6nYiuADWwKB4C2WSw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
 | 
						|
 | 
						|
</head>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
<body>
 | 
						|
<center>
 | 
						|
 | 
						|
 | 
						|
 | 
						|
   <nav class="navbar navbar-expand-lg bg-body-tertiary shadow">
 | 
						|
        <div class="container-fluid">
 | 
						|
          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
 | 
						|
            <span class="navbar-toggler-icon"></span>
 | 
						|
          </button>
 | 
						|
          <div class="collapse navbar-collapse" id="navbarSupportedContent">
 | 
						|
            <ul class="navbar-nav me-auto mb-2 mb-lg-0">
 | 
						|
              <li class="nav-item dropdown">
 | 
						|
                <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
 | 
						|
                  Nodes
 | 
						|
                </a>
 | 
						|
                <ul class="dropdown-menu">
 | 
						|
<li><a class="dropdown-item" href="/">localhost</a></li>
 | 
						|
<li><hr class="dropdown-divider"></li>
 | 
						|
{% for nav_item in client %}
 | 
						|
<li><a class="dropdown-item" href="/n/{{ nav_item }}">{{ nav_item }}</a></li>
 | 
						|
{% endfor %}
 | 
						|
                </ul>
 | 
						|
              </li>
 | 
						|
            </ul>
 | 
						|
          </div>
 | 
						|
        </div>
 | 
						|
      </nav>
 | 
						|
 | 
						|
<br>
 | 
						|
<div class="container">
 | 
						|
<div class="row">
 | 
						|
<div class="col-4">
 | 
						|
<div class="card">
 | 
						|
<div class="card-header">
 | 
						|
Environnement
 | 
						|
</div>
 | 
						|
<div class="card-body">
 | 
						|
<h5 class="display-6">{{ full['hostname'] }}</h5>
 | 
						|
<br> CPU : {{ full['cpu_number'] }}
 | 
						|
<br> vCPU : {{ full['vcpu'] }}
 | 
						|
<br> Memory : {{ full['mem_max']}}
 | 
						|
<br> Node : {{ node }}
 | 
						|
<br> Up since : {{ boottime }}
 | 
						|
</div></div>
 | 
						|
</div>
 | 
						|
 | 
						|
<div class="col-8">
 | 
						|
	<div class="card">
 | 
						|
		<div class="card-header">
 | 
						|
			Monitor
 | 
						|
		</div>
 | 
						|
		<div class="card-body">
 | 
						|
			<canvas id="canvas"></canvas>
 | 
						|
		</div>
 | 
						|
	</div>
 | 
						|
</div>
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
<div class="card">
 | 
						|
<div class="card-header">
 | 
						|
    Usage
 | 
						|
</div>
 | 
						|
<div class="card-body">
 | 
						|
CPU
 | 
						|
<div class="progress">
 | 
						|
<div id="cpubar" class="progress-bar progress-bar-striped" role="progressbar" style="width: {{ full['cpu']['percent'] }}%;" aria-valuenow={{ full['cpu']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['cpu']['percent'] }}%</div>
 | 
						|
</div>
 | 
						|
<small class="form-text text-muted">
 | 
						|
user : {{ full['cpu']['time_user'] }} / nice : {{ full['cpu']['time_nice'] }} / system : {{ full['cpu']['time_system'] }} / idle : {{ full['cpu']['time_idle'] }} / iowait : {{ full['cpu']['time_iowait'] }} / irq : {{ full['cpu']['time_irq'] }} / softirq : {{ full['cpu']['time_softirq'] }} / steal : {{ full['cpu']['time_steal'] }} / guest : {{ full['cpu']['time_guest'] }} / guest nice : {{ full['cpu']['time_guest_nice'] }}
 | 
						|
</small>
 | 
						|
<br>
 | 
						|
MEM
 | 
						|
<div class="progress">
 | 
						|
  <div id="membar" class="progress-bar bg-warning progress-bar-striped" role="progressbar" style="width: {{ full['mem']['percent'] }}%;" aria-valuenow={{ full['mem']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['mem']['percent'] }}%</div>
 | 
						|
</div>
 | 
						|
<small class="form-text text-muted">
 | 
						|
total : {{ full['mem']['total'] }} / available : {{ full['mem']['available'] }} / used : {{ full['mem']['used'] }} / free : {{ full['mem']['free'] }} / active : {{ full['mem']['active'] }} / inactive : {{ full['mem']['inactive'] }} / buffers : {{ full['mem']['buffers'] }} / cached : {{ full['mem']['cached'] }} / shared : {{ full['mem']['shared'] }} / slab : {{ full['mem']['slab'] }}
 | 
						|
</small>
 | 
						|
<br>
 | 
						|
SWAP
 | 
						|
<div class="progress">
 | 
						|
  <div id="swapbar" class="progress-bar bg-danger progress-bar-striped" role="progressbar" style="width: {{ full['swap']['percent'] }}%;" aria-valuenow={{ full['swap']['percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full['swap']['percent'] }}%</div>
 | 
						|
</div>
 | 
						|
<small class="form-text text-muted">
 | 
						|
total : {{ full['swap']['total'] }} / used : {{ full['swap']['used'] }} / free : {{ full['swap']['free'] }} / sin : {{ full['swap']['sin'] }} / sout : {{ full['swap']['sout'] }}
 | 
						|
</small>
 | 
						|
</div>
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
 | 
						|
<div class="card">
 | 
						|
  <div class="card-header">
 | 
						|
    Disks
 | 
						|
  </div>
 | 
						|
  <div class="card-body">
 | 
						|
{% for key in full %}
 | 
						|
{% if key.startswith('disk_') %}
 | 
						|
{{ full[key]['mountpoint'] }}
 | 
						|
<div class="progress">
 | 
						|
  <div class="progress-bar bg-info" role="progressbar" style="width: {{ full[key]['size_percent'] }}%;" aria-valuenow={{ full[key]['size_percent'] }} aria-valuemin="0" aria-valuemax="100">{{ full[key]['size_percent'] }}%</div>
 | 
						|
</div>
 | 
						|
<small class="form-text text-muted">
 | 
						|
total : {{ full[key]['size_total'] }} / used : {{ full[key]['size_used'] }} / free : {{ full[key]['size_free'] }} / device : {{ full[key]['device'] }} / fstype : {{ full[key]['fstype'] }} / opt: {{ full[key]['opts'] }} / maxfile : {{ full[key]['maxfile'] }} / maxpath : {{ full[key]['maxpath'] }}
 | 
						|
</small>
 | 
						|
</br>
 | 
						|
{% endif %}
 | 
						|
{% endfor %}
 | 
						|
  </div>
 | 
						|
</div>
 | 
						|
<br>
 | 
						|
 | 
						|
<div class="card">
 | 
						|
  <div class="card-header">
 | 
						|
    Network
 | 
						|
  </div>
 | 
						|
  <div class="card-body">
 | 
						|
<table class="table">
 | 
						|
<tr><td>Name</td><td>IPv4</td><td>Netmask v4</td><td>IPv6</td><td>Netmask v6</td><td>Sent</td><td>Received</td></tr>
 | 
						|
{% for key in full %}
 | 
						|
{% if key.startswith('net_') %}
 | 
						|
<tr><td>{{ full[key]['name'] }}</td><td>{{ full[key]['address_v4'] }}</td><td>{{ full[key]['netmask_v4'] }}</td><td>{{ full[key]['address_v6'] }}</td><td>{{ full[key]['netmask_v6'] }}</td><td>{{ full[key]['bytes_sent'] }}</td><td>{{ full[key]['bytes_recv'] }}</td><tr>
 | 
						|
{% endif %}
 | 
						|
{% endfor %}
 | 
						|
</table>
 | 
						|
  </div>
 | 
						|
</div>
 | 
						|
 | 
						|
<script>
 | 
						|
    $(document).ready(function () {
 | 
						|
        const config = {
 | 
						|
            type: 'line',
 | 
						|
            data: {
 | 
						|
                labels: Array(60).fill("0000-00-00 00:00:00"),
 | 
						|
                datasets: [{
 | 
						|
                    label: "CPU %",
 | 
						|
                    backgroundColor: 'rgb(0, 191, 255)',
 | 
						|
                    borderColor: 'rgb(0, 191, 255)',
 | 
						|
                    data: Array(60).fill(null),
 | 
						|
                    fill: false,
 | 
						|
                    pointRadius: 0,
 | 
						|
                },{
 | 
						|
                    label: "Mem %",
 | 
						|
                    backgroundColor: 'rgb(255,200,20)',
 | 
						|
                    borderColor: 'rgb(255,200,20)',
 | 
						|
                    data: Array(60).fill(null),
 | 
						|
                    fill: false,
 | 
						|
                    pointRadius: 0,
 | 
						|
                },{
 | 
						|
                    label: "Swap %",
 | 
						|
                    backgroundColor: 'rgb(255, 20, 100)',
 | 
						|
                    borderColor: 'rgb(255, 20, 100)',
 | 
						|
                    data: Array(60).fill(null),
 | 
						|
                    fill: false,
 | 
						|
                    pointRadius: 0,
 | 
						|
                }],
 | 
						|
            },
 | 
						|
            options: {
 | 
						|
                responsive: true,
 | 
						|
                title: {
 | 
						|
                    display: false,
 | 
						|
                },
 | 
						|
                tooltips: {
 | 
						|
                    mode: 'index',
 | 
						|
                    intersect: false,
 | 
						|
                },
 | 
						|
                hover: {
 | 
						|
                    mode: 'nearest',
 | 
						|
                    intersect: true
 | 
						|
                },
 | 
						|
                scales: {
 | 
						|
                    xAxes: [{
 | 
						|
                        display: false,
 | 
						|
                        scaleLabel: {
 | 
						|
                            display: true,
 | 
						|
                            labelString: 'Time'
 | 
						|
                        }
 | 
						|
                    }],
 | 
						|
                    yAxes: [{
 | 
						|
                        display: true,
 | 
						|
                        scaleLabel: [{
 | 
						|
                            display: true,
 | 
						|
                            labelString: 'CPU'
 | 
						|
                        },{
 | 
						|
                            display: true,
 | 
						|
                            labelString: 'Mem'
 | 
						|
                        },{
 | 
						|
                            display: true,
 | 
						|
                            labelString: 'Swap'
 | 
						|
                        }]
 | 
						|
                    }]
 | 
						|
                }
 | 
						|
            }
 | 
						|
        };
 | 
						|
 | 
						|
        const context = document.getElementById('canvas').getContext('2d');
 | 
						|
        const lineChart = new Chart(context, config);
 | 
						|
        const source = new EventSource("/chart-ressources/{{ node }}");
 | 
						|
        source.onmessage = function (event) {
 | 
						|
            const data = JSON.parse(event.data);
 | 
						|
            if (config.data.labels.length === 60) {
 | 
						|
                config.data.labels.shift();
 | 
						|
                config.data.datasets[0].data.shift();
 | 
						|
                config.data.datasets[1].data.shift();
 | 
						|
                config.data.datasets[2].data.shift();
 | 
						|
            }
 | 
						|
            config.data.labels.push(data.time);
 | 
						|
            config.data.datasets[0].data.push(data.cpu);
 | 
						|
            config.data.datasets[1].data.push(data.mem);
 | 
						|
            config.data.datasets[2].data.push(data.swap);
 | 
						|
            lineChart.update();
 | 
						|
            $("#cpubar").html(data.cpu+"%");
 | 
						|
            $("#membar").html(data.mem+"%");
 | 
						|
            $("#swapbar").html(data.swap+"%");
 | 
						|
            var element_cpubar = document.getElementById("cpubar");
 | 
						|
            var element_membar = document.getElementById("membar");
 | 
						|
            var element_swapbar = document.getElementById("swapbar");
 | 
						|
 | 
						|
            element_cpubar.style.width = data.cpu+"%"
 | 
						|
            element_membar.style.width = data.mem+"%"
 | 
						|
            element_swapbar.style.width = data.swap+"%"
 | 
						|
        }
 | 
						|
    });
 | 
						|
 | 
						|
 | 
						|
</script>
 | 
						|
 | 
						|
</body>
 | 
						|
</html>
 |