mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-19 23:33:43 +00:00
Merge pull request #669 from GNS3/System-status
Support for system status
This commit is contained in:
@ -147,6 +147,12 @@
|
||||
<mat-icon>center_focus_strong</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
|
||||
<mat-toolbar-row *ngIf="!readonly">
|
||||
<button matTooltip="Go to system status" mat-icon-button routerLink="/server/{{server.id}}/systemstatus">
|
||||
<mat-icon>info</mat-icon>
|
||||
</button>
|
||||
</mat-toolbar-row>
|
||||
</mat-toolbar>
|
||||
</div>
|
||||
|
||||
|
@ -0,0 +1,155 @@
|
||||
<mat-card>
|
||||
<div class="wrapper">
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.cpu_usage_percent"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="'CPU usage percent'"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.disk_usage_percent"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="'Disk usage percent'"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.memory_usage_percent"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="'Memory usage percent'"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.swap_usage_percent"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="'SWAP usage percent'"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.load_average_percent[0]"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="['Load average percent', '(last 1 minute)']"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.load_average_percent[1]"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="['Load average percent', '(last 5 minutes)']"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
|
||||
<circle-progress
|
||||
[percent]="computeStatistics.statistics.load_average_percent[2]"
|
||||
[radius]="100"
|
||||
[outerStrokeWidth]="8"
|
||||
[innerStrokeWidth]="6"
|
||||
[outerStrokeColor]="'#0097a7'"
|
||||
[innerStrokeColor]="'#007380'"
|
||||
[animation]="true"
|
||||
[animationDuration]="300"
|
||||
[unitsColor]="'#C0C0C0'"
|
||||
[unitsFontSize]="20"
|
||||
[titleColor]="'#C0C0C0'"
|
||||
[titleFontSize]="30"
|
||||
[subtitle]="['Load average percent', '(last 15 minutes)']"
|
||||
[subtitleColor]="'#C0C0C0'"
|
||||
[subtitleFontSize]="15"
|
||||
></circle-progress>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Memory total: {{formatBytes(computeStatistics.statistics.memory_total)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Memory used: {{formatBytes(computeStatistics.statistics.memory_used)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Memory free: {{formatBytes(computeStatistics.statistics.memory_free)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Swap total: {{formatBytes(computeStatistics.statistics.swap_total)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Swap used: {{formatBytes(computeStatistics.statistics.swap_used)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
<mat-chip-list>
|
||||
<mat-chip color="primary" selected>Swap free: {{formatBytes(computeStatistics.statistics.swap_free)}}</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
</mat-card>
|
@ -0,0 +1,6 @@
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 20px;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
import { Component, OnInit, Input } from "@angular/core";
|
||||
import { ComputeStatistics } from '../../../models/computeStatistics';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-chart',
|
||||
templateUrl: './status-chart.component.html',
|
||||
styleUrls: ['./status-chart.component.scss']
|
||||
})
|
||||
export class StatusChartComponent implements OnInit {
|
||||
@Input() computeStatistics: ComputeStatistics;
|
||||
|
||||
constructor() {}
|
||||
|
||||
ngOnInit() {}
|
||||
|
||||
formatBytes(bytes, decimals = 2) {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
|
||||
const k = 1024;
|
||||
const dm = decimals < 0 ? 0 : decimals;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
}
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
<div *ngFor='let statistics of computeStatistics'>
|
||||
{{statistics.compute_name}}
|
||||
<app-status-chart [computeStatistics]="statistics"></app-status-chart>
|
||||
</div>
|
@ -0,0 +1,47 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ComputeService } from '../../../services/compute.service';
|
||||
import { ComputeStatistics } from '../../../models/computeStatistics';
|
||||
import { ServerService } from '../../../services/server.service';
|
||||
import { Server } from '../../../models/server';
|
||||
import { ToasterService } from '../../../services/toaster.service';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-status-info',
|
||||
templateUrl: './status-info.component.html',
|
||||
styleUrls: ['./status-info.component.scss']
|
||||
})
|
||||
export class StatusInfoComponent implements OnInit {
|
||||
public serverId: string = "";
|
||||
public computeStatistics: ComputeStatistics[] = [];
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private computeService: ComputeService,
|
||||
private serverService: ServerService,
|
||||
private toasterService: ToasterService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serverId = this.route.snapshot.paramMap.get("server_id");
|
||||
this.getStatistics();
|
||||
}
|
||||
|
||||
getStatistics() {
|
||||
this.serverService.get(Number(this.serverId)).then((server: Server) => {
|
||||
this.computeService.getStatistics(server).subscribe(
|
||||
(statistics: ComputeStatistics[]) => {
|
||||
this.computeStatistics = statistics;
|
||||
setTimeout(() =>
|
||||
{
|
||||
this.getStatistics();
|
||||
},
|
||||
10000);
|
||||
}),
|
||||
error => {
|
||||
this.toasterService.error('Required server version is 2.3')
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
<div class="content">
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">System status</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="default-content">
|
||||
<app-status-info></app-status-info>
|
||||
</div>
|
||||
</div>
|
20
src/app/components/system-status/system-status.component.ts
Normal file
20
src/app/components/system-status/system-status.component.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-system-status',
|
||||
templateUrl: './system-status.component.html',
|
||||
styleUrls: ['./system-status.component.scss']
|
||||
})
|
||||
export class SystemStatusComponent implements OnInit {
|
||||
public serverId: string = "";
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.serverId = this.route.snapshot.paramMap.get("server_id");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user