[web-app] 监控历史图表详情

This commit is contained in:
tomsun28
2022-01-30 14:00:46 +08:00
parent ef7f71952b
commit c661dfcdbb
15 changed files with 493 additions and 96 deletions

View File

@@ -1,49 +1,9 @@
<nz-card *ngIf="isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead>
<tr>
<th style="text-align: center" *ngFor="let field of fields">{{ field.name }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let valueRow of smallTable.data">
<td *ngFor="let value of valueRow.values">{{ value.origin }}</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<nz-card *ngIf="!isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead>
<tr>
<th style="text-align: center">属性</th>
<th style="text-align: center"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let field of fields; let i = index">
<td>{{ field.name }}</td>
<td>{{ rowValues[i].origin + ' ' + (field.unit ? field.unit : '') }}</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<ng-template #monitor_metrics_card_title>
<p style="font-size: small; text-align: center; margin-bottom: 3px; color: #0c0c0c">{{ metrics }}</p>
<div>
<a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')">
<i nz-icon nzType="field-time" nzTheme="outline"></i
></a>
<i style="font-size: 0.3px; font-weight: normal; color: rgba(84, 83, 83, 0.89)">采集时间:{{ time | _date: 'HH:mm:ss' }}</i>
</div>
</ng-template>
<!--<nz-card *ngIf="!isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true"-->
<!-- [nzTitle]="monitor_metrics_card_title" >-->
<!-- <div *ngFor="let field of fields;let i = index;" nz-row nzGutter="16">-->
<!-- <div nz-col nzSpan="10"><p style="text-align: right">{{field.name}}</p></div>-->
<!-- <div nz-col nzSpan="14"><p style="text-align: left">{{rowValues[i].origin}}</p></div>-->
<!-- </div>-->
<!--</nz-card>-->
<div
echarts
[options]="eChartOption"
theme="default"
[autoResize]="true"
[loading]="loading"
(chartInit)="onChartInit($event)"
style="width: 500px; height: 400px; margin-left: 20px"
></div>

View File

@@ -8,8 +8,9 @@ describe('MonitorDataChartComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MonitorDataChartComponent]
}).compileComponents();
declarations: [ MonitorDataChartComponent ]
})
.compileComponents();
});
beforeEach(() => {

View File

@@ -1,11 +1,13 @@
import { Component, Input, OnInit } from '@angular/core';
import { EChartsOption } from 'echarts';
import { finalize } from 'rxjs/operators';
import { MonitorService } from '../../../service/monitor.service';
@Component({
selector: 'app-monitor-data-chart',
templateUrl: './monitor-data-chart.component.html',
styleUrls: ['./monitor-data-chart.component.less']
styles: []
})
export class MonitorDataChartComponent implements OnInit {
@Input()
@@ -14,41 +16,254 @@ export class MonitorDataChartComponent implements OnInit {
}
set monitorId(monitorId: number) {
this._monitorId = monitorId;
this.loadData();
}
private _monitorId!: number;
@Input()
app!: string;
@Input()
metrics!: string;
time!: any;
fields!: any[];
valueRows!: any[];
rowValues!: any[];
isTable: boolean = true;
@Input()
metric!: string;
@Input()
unit!: string;
eChartOption!: EChartsOption;
lineHistoryTheme!: EChartsOption;
loading: boolean = true;
echartsInstance!: any;
// 查询历史数据时间段 默认最近6小时
timePeriod: string = '6h';
constructor(private monitorSvc: MonitorService) {}
ngOnInit(): void {}
loadData() {
// 读取实时指标数据
let metricData$ = this.monitorSvc.getMonitorMetricsData(this.monitorId, this.metrics).subscribe(
message => {
metricData$.unsubscribe();
if (message.code === 0) {
this.time = message.data.time;
this.fields = message.data.fields;
this.valueRows = message.data.valueRows;
if (this.valueRows.length == 1) {
this.isTable = false;
this.rowValues = this.valueRows[0].values;
}
} else {
console.error(message.msg);
ngOnInit(): void {
this.lineHistoryTheme = {
title: {
text: `${this.metrics}.${this.metric}`,
textStyle: {
fontSize: 16,
fontFamily: 'monospace',
textShadowOffsetX: 10
}
},
error => {
metricData$.unsubscribe();
toolbox: {
show: true,
orient: 'vertical',
feature: {
dataZoom: {
yAxisIndex: 'none',
title: {
zoom: '区域缩放',
back: '缩放还原'
},
emphasis: {
iconStyle: {
textPosition: 'left'
}
}
},
saveAsImage: {
title: '保存图片',
emphasis: {
iconStyle: {
textPosition: 'left'
}
}
},
myPeriod1h: {
show: true,
title: '查询近1小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData('1h');
}
},
myPeriod6h: {
show: true,
title: '查询近6小时',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData('6h');
}
},
myPeriod1d: {
show: true,
title: '查询近1天',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData('1d');
}
},
myPeriod1w: {
show: true,
title: '查询近1周',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData('1w');
}
},
myPeriod4w: {
show: true,
title: '查询近1月',
icon: 'path://M827.871087 196.128913C743.498468 111.756293 631.321596 65.290005 512 65.290005c-119.319549 0-231.499491 46.465265-315.871087 130.837884S65.290005 392.680451 65.290005 512s46.465265 231.499491 130.837884 315.871087 196.551538 130.837884 315.871087 130.837884c119.321596 0 231.499491-46.465265 315.871087-130.837884S958.708971 631.319549 958.708971 512 912.243707 280.500509 827.871087 196.128913zM531.556405 917.246651l0-74.145697c0-11.31572-9.174963-20.491707-20.491707-20.491707-11.316743 0-20.491707 9.174963-20.491707 20.491707l0 74.059739C283.276738 906.322857 116.693746 739.164766 106.755396 531.634176l72.351841 0c11.31572 0 20.491707-9.174963 20.491707-20.491707 0-11.31572-9.174963-20.491707-20.491707-20.491707l-72.273047 0c10.769274-206.737528 177.01253-373.005342 383.740848-383.813502l0 72.346725c0 11.316743 9.174963 20.491707 20.491707 20.491707 11.31572 0 20.491707-9.17394 20.491707-20.491707L531.558451 106.752326c207.593012 9.901511 374.807385 176.539762 385.609405 383.89946l-74.142627 0c-11.316743 0-20.491707 9.174963-20.491707 20.491707 0 11.316743 9.174963 20.491707 20.491707 20.491707l74.220399 0C907.275555 739.78796 739.720422 907.317511 531.556405 917.246651z;M532.098757 503.118726 532.098757 258.240529c0-11.316743-9.174963-20.491707-20.491707-20.491707-11.31572 0-20.491707 9.17394-20.491707 20.491707l0 254.66612c0 7.858992 4.429893 14.677281 10.924817 18.114566L693.447539 722.42757c4.002151 4.000104 9.245572 6.001691 14.490016 6.001691s10.487865-2.001587 14.490016-6.001691c8.002254-8.002254 8.002254-20.977777 0-28.980032L532.098757 503.118726z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData('4w');
}
},
myRefresh: {
show: true,
title: '刷新',
icon: 'path://M663.881 339.763l274.021-0.742 0.058-13.271 0.699 0c-0.204-0.48-0.495-0.945-0.699-1.426L938.658 65l-23.776 0.044L914.3 280.41C835.9 151.374 694.321 65 532.342 65c-246.869 0-447 200.132-447 447 0 246.84 200.131 447 447 447 180.343 0 335.657-106.919 406.316-260.75l-33.176 0C836.948 835.027 695.456 929.2 532.342 929.2c-230.048 0-417.2-187.152-417.2-417.2s187.152-417.2 417.2-417.2c158.895 0 297.068 89.487 367.466 220.547l-235.868 0.64L663.881 339.763z',
emphasis: {
iconStyle: {
textPosition: 'left'
}
},
onclick: () => {
this.loadData();
}
}
}
},
tooltip: {
trigger: 'axis',
formatter: function (params: any) {
let time: number = params[0].value[0];
var date = new Date(time);
let seriesName = params[0].seriesName;
let month = (date.getMonth() + 1).toString().padStart(2, '0');
let day = date.getDate().toString().padStart(2, '0');
if (seriesName == null || seriesName == 'NULL') {
return `${date.getFullYear()}/${month}/${day} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()} -- ${
params[0].value[1]
}`;
} else {
return `${seriesName} ${date.getFullYear()}/${month}/${day} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()} -- ${
params[0].value[1]
}`;
}
}
},
xAxis: {
type: 'time',
splitLine: {
show: false
}
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
splitLine: {
show: true
}
}
);
};
if (this.unit != undefined || this.unit != null) {
// @ts-ignore
this.lineHistoryTheme.title?.subtext = `单位 ${this.unit}`;
}
this.loadData();
}
loadData(timePeriod?: string) {
if (timePeriod != undefined) {
this.timePeriod = timePeriod;
}
// 读取指标历史数据
this.loading = true;
let metricData$ = this.monitorSvc
.getMonitorMetricHistoryData(this.monitorId, this.app, this.metrics, this.metric, this.timePeriod, false)
.pipe(
finalize(() => {
this.loading = false;
metricData$.unsubscribe();
})
)
.subscribe(
message => {
if (message.code === 0 && message.data.values != undefined) {
let values: Record<string, any> = message.data.values;
let legend: string[] = [];
Object.keys(values).forEach(key => {
legend.push(key);
});
if (legend.length > 1) {
this.lineHistoryTheme.legend = {
orient: 'vertical',
data: legend
};
}
Object.keys(values).forEach(key => {
let seriesData: Array<{ value: any }> = [];
values[key].forEach((item: { time: number; origin: any }) => {
seriesData.push({
value: [item.time, item.origin]
});
});
this.lineHistoryTheme.series = [];
this.lineHistoryTheme.series.push({
name: key,
type: 'line',
smooth: true,
showSymbol: false,
data: seriesData
});
this.eChartOption = this.lineHistoryTheme;
if (this.echartsInstance != undefined) {
this.echartsInstance.setOption(this.eChartOption, {
replaceMerge: ['xAxis', 'yAxis', 'series']
});
}
});
} else {
this.eChartOption = this.lineHistoryTheme;
this.eChartOption.title = {
text: `${this.metrics}.${this.metric}` + '\n\n\n' + '暂无数据',
textStyle: {
fontSize: 16,
fontFamily: 'monospace',
textShadowOffsetX: 10
},
left: 'center',
top: 'center'
};
if (this.echartsInstance != undefined) {
this.echartsInstance.setOption(this.eChartOption, {
replaceMerge: ['title']
});
}
}
},
error => {
console.error(error.msg);
}
);
}
onChartInit(ec: any) {
this.echartsInstance = ec;
}
}

View File

@@ -0,0 +1,49 @@
<nz-card *ngIf="isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead>
<tr>
<th style="text-align: center" *ngFor="let field of fields">{{ field.name }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let valueRow of smallTable.data">
<td *ngFor="let value of valueRow.values">{{ value.origin }}</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<nz-card *ngIf="!isTable" nzHoverable style="height: auto; margin-left: 14px" [nzBordered]="true" [nzTitle]="monitor_metrics_card_title">
<nz-table #smallTable nzSize="small" nzNoResult="No Metrics Data" nzFrontPagination="false" [nzData]="valueRows">
<thead>
<tr>
<th style="text-align: center">属性</th>
<th style="text-align: center"></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let field of fields; let i = index">
<td>{{ field.name }}</td>
<td>{{ rowValues[i].origin + ' ' + (field.unit ? field.unit : '') }}</td>
</tr>
</tbody>
</nz-table>
</nz-card>
<ng-template #monitor_metrics_card_title>
<p style="font-size: small; text-align: center; margin-bottom: 3px; color: #0c0c0c">{{ metrics }}</p>
<div>
<a nz-popover [nzPopoverContent]="'最近采集时间 ' + (time | _date: 'yyyy-MM-dd HH:mm:ss')">
<i nz-icon nzType="field-time" nzTheme="outline"></i
></a>
<i style="font-size: 0.3px; font-weight: normal; color: rgba(84, 83, 83, 0.89)">采集时间:{{ time | _date: 'HH:mm:ss' }}</i>
</div>
</ng-template>
<!--<nz-card *ngIf="!isTable" nzHoverable style="height:auto;margin-left: 14px;" [nzBordered]="true"-->
<!-- [nzTitle]="monitor_metrics_card_title" >-->
<!-- <div *ngFor="let field of fields;let i = index;" nz-row nzGutter="16">-->
<!-- <div nz-col nzSpan="10"><p style="text-align: right">{{field.name}}</p></div>-->
<!-- <div nz-col nzSpan="14"><p style="text-align: left">{{rowValues[i].origin}}</p></div>-->
<!-- </div>-->
<!--</nz-card>-->

View File

@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { MonitorDataTableComponent } from './monitor-data-table.component';
describe('MonitorDataChartComponent', () => {
let component: MonitorDataTableComponent;
let fixture: ComponentFixture<MonitorDataTableComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [MonitorDataTableComponent]
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MonitorDataTableComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,55 @@
import { Component, Input } from '@angular/core';
import { MonitorService } from '../../../service/monitor.service';
@Component({
selector: 'app-monitor-data-table',
templateUrl: './monitor-data-table.component.html',
styleUrls: ['./monitor-data-table.component.less']
})
export class MonitorDataTableComponent {
@Input()
get monitorId(): number {
return this._monitorId;
}
set monitorId(monitorId: number) {
this._monitorId = monitorId;
// 需将monitorId作为输入参数的最后一个 这样在执行loadData时其它入参才有值
this.loadData();
}
private _monitorId!: number;
@Input()
metrics!: string;
time!: any;
fields!: any[];
valueRows!: any[];
rowValues!: any[];
isTable: boolean = true;
constructor(private monitorSvc: MonitorService) {}
loadData() {
// 读取实时指标数据
let metricData$ = this.monitorSvc.getMonitorMetricsData(this.monitorId, this.metrics).subscribe(
message => {
metricData$.unsubscribe();
if (message.code === 0) {
this.time = message.data.time;
this.fields = message.data.fields;
this.valueRows = message.data.valueRows;
if (this.valueRows.length == 1) {
this.isTable = false;
this.rowValues = this.valueRows[0].values;
}
} else {
console.error(message.msg);
}
},
error => {
console.error(error.msg);
metricData$.unsubscribe();
}
);
}
}

View File

@@ -103,11 +103,28 @@
<nz-tab [nzTitle]="titleTemplate">
<ng-template #titleTemplate>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
监控数据报告详情
监控实时数据详情
</ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let metric of metrics; let i = index">
<app-monitor-data-chart [metrics]="metric" [monitorId]="monitorId"></app-monitor-data-chart>
<app-monitor-data-table [metrics]="metric" [monitorId]="monitorId"></app-monitor-data-table>
</div>
</div>
</nz-tab>
<nz-tab [nzTitle]="title2Template" (nzClick)="initMetricChart()">
<ng-template #title2Template>
<i nz-icon nzType="pic-right" style="margin-left: 10px"></i>
监控历史图表详情
</ng-template>
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap">
<div *ngFor="let item of chartMetrics; let i = index">
<app-monitor-data-chart
[app]="app"
[metrics]="item.metrics"
[metric]="item.metric"
[unit]="item.unit"
[monitorId]="monitorId"
></app-monitor-data-chart>
</div>
</div>
</nz-tab>

View File

@@ -1,10 +1,10 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
import { TitleService } from '@delon/theme';
import { switchMap } from 'rxjs/operators';
import { ActivatedRoute, ParamMap } from '@angular/router';
import { finalize, switchMap } from 'rxjs/operators';
import { Monitor } from '../../../pojo/Monitor';
import { Param } from '../../../pojo/Param';
import { AppDefineService } from '../../../service/app-define.service';
import { MonitorService } from '../../../service/monitor.service';
@Component({
@@ -13,14 +13,15 @@ import { MonitorService } from '../../../service/monitor.service';
styleUrls: ['./monitor-detail.component.less']
})
export class MonitorDetailComponent implements OnInit {
constructor(private monitorSvc: MonitorService, private route: ActivatedRoute, private router: Router, private titleSvc: TitleService) {}
constructor(private monitorSvc: MonitorService, private route: ActivatedRoute, private appDefineSvc: AppDefineService) {}
isSpinning: boolean = false;
monitorId!: number;
app: string | undefined;
monitor: Monitor | undefined;
app!: string;
monitor!: Monitor;
options: any;
port: number | undefined;
metrics!: string[];
chartMetrics: any[] = [];
ngOnInit(): void {
this.route.paramMap
@@ -53,6 +54,45 @@ export class MonitorDetailComponent implements OnInit {
},
error => {
this.isSpinning = false;
console.error(error.msg);
}
);
}
initMetricChart() {
// 查询过滤出此监控下可计算聚合的数字指标
const define$ = this.appDefineSvc
.getAppDefine(this.app)
.pipe(
finalize(() => {
define$.unsubscribe();
})
)
.subscribe(
message => {
if (message.code === 0 && message.data != undefined) {
this.chartMetrics = [];
let metrics = message.data.metrics;
metrics.forEach((metric: { name: any; fields: any }) => {
let fields = metric.fields;
if (fields != undefined) {
fields.forEach((field: { type: number; field: any; unit: any }) => {
if (field.type == 0) {
this.chartMetrics.push({
metrics: metric.name,
metric: field.field,
unit: field.unit
});
}
});
}
});
} else {
console.warn(message.msg);
}
},
error => {
console.error(error.msg);
}
);
}

View File

@@ -10,6 +10,7 @@ import { NzTagModule } from 'ng-zorro-antd/tag';
import { NgxEchartsModule } from 'ngx-echarts';
import { MonitorDataChartComponent } from './monitor-data-chart/monitor-data-chart.component';
import { MonitorDataTableComponent } from './monitor-data-table/monitor-data-table.component';
import { MonitorDetailComponent } from './monitor-detail/monitor-detail.component';
import { MonitorEditComponent } from './monitor-edit/monitor-edit.component';
import { MonitorListComponent } from './monitor-list/monitor-list.component';
@@ -21,6 +22,7 @@ const COMPONENTS: Array<Type<void>> = [
MonitorEditComponent,
MonitorListComponent,
MonitorDetailComponent,
MonitorDataTableComponent,
MonitorDataChartComponent
];

View File

@@ -21,6 +21,13 @@ export class AppDefineService {
return this.http.get<Message<ParamDefine[]>>(paramDefineUri);
}
public getAppDefine(app: string | undefined | null): Observable<Message<any>> {
if (app === null || app === undefined) {
console.log('getAppDefine app can not null');
}
return this.http.get<Message<any>>(`/apps/${app}/define`);
}
public getAppHierarchy(): Observable<Message<any>> {
let httpParams = new HttpParams().append('lang', 'zh-CN');
const options = { params: httpParams };

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
const Authorization = 'Authorization';
const refreshToken = 'refresh-token';
const AuthorizationConst = 'Authorization';
const RefreshTokenConst = 'refresh-token';
@Injectable({
providedIn: 'root'
@@ -19,23 +19,23 @@ export class LocalStorageService {
}
public getAuthorizationToken(): string | null {
return this.getData(Authorization);
return this.getData(AuthorizationConst);
}
public getRefreshToken(): string | null {
return this.getData(refreshToken);
return this.getData(RefreshTokenConst);
}
public storageRefreshToken(token: string) {
return this.putData(refreshToken, token);
return this.putData(RefreshTokenConst, token);
}
public storageAuthorizationToken(token: string) {
return this.putData(Authorization, token);
return this.putData(AuthorizationConst, token);
}
public hasAuthorizationToken() {
return localStorage.getItem(Authorization) != null;
return localStorage.getItem(AuthorizationConst) != null;
}
public clear() {

View File

@@ -107,6 +107,24 @@ export class MonitorService {
return this.http.get<Message<any>>(`/monitor/${monitorId}/metrics/${metrics}`);
}
public getMonitorMetricHistoryData(
monitorId: number,
app: string,
metrics: string,
metric: string,
history: string,
interval: boolean
): Observable<Message<any>> {
let metricFull = `${app}.${metrics}.${metric}`;
let httpParams = new HttpParams();
httpParams = httpParams.appendAll({
history: history,
interval: interval
});
const options = { params: httpParams };
return this.http.get<Message<any>>(`/monitor/${monitorId}/metric/${metricFull}`, options);
}
public getAppsMonitorSummary(): Observable<Message<any>> {
return this.http.get<Message<any>>(summary_uri);
}