diff --git a/manager/src/main/java/com/usthe/manager/controller/AppController.java b/manager/src/main/java/com/usthe/manager/controller/AppController.java index 039dad7..d6e1a96 100644 --- a/manager/src/main/java/com/usthe/manager/controller/AppController.java +++ b/manager/src/main/java/com/usthe/manager/controller/AppController.java @@ -1,8 +1,9 @@ package com.usthe.manager.controller; import com.usthe.common.entity.dto.Message; -import com.usthe.manager.pojo.dto.Hierarchy; +import com.usthe.common.entity.job.Job; import com.usthe.common.entity.manager.ParamDefine; +import com.usthe.manager.pojo.dto.Hierarchy; import com.usthe.manager.service.AppService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -40,6 +41,14 @@ public class AppController { return ResponseEntity.ok(new Message<>(paramDefines)); } + @GetMapping(path = "/{app}/define") + @ApiOperation(value = "查询监控类型的结构定义", notes = "根据app查询指定监控类型的定义结构") + public ResponseEntity> queryAppDefine( + @ApiParam(value = "监控类型名称", example = "api") @PathVariable("app") String app) { + Job define = appService.getAppDefine(app.toLowerCase()); + return ResponseEntity.ok(new Message<>(define)); + } + @GetMapping(path = "/hierarchy") @ApiOperation(value = "查询全部层级的监控类型", notes = "查询所有监控类型,以层级结构输出") public ResponseEntity>> queryAppsHierarchy( diff --git a/manager/src/main/resources/db/schema.sql b/manager/src/main/resources/db/schema.sql index 1334d56..65f581a 100644 --- a/manager/src/main/resources/db/schema.sql +++ b/manager/src/main/resources/db/schema.sql @@ -31,7 +31,7 @@ CREATE TABLE param id bigint not null auto_increment comment '参数ID', monitor_id bigint not null comment '监控ID', field varchar(100) not null comment '参数标识符', - value varchar(255) not null comment '参数值,最大字符长度255', + value varchar(255) comment '参数值,最大字符长度255', type tinyint not null default 0 comment '参数类型 0:数字 1:字符串 2:加密串', gmt_create timestamp default current_timestamp comment 'create time', gmt_update datetime default current_timestamp on update current_timestamp comment 'update time', diff --git a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.html b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.html index 1b680df..e70dde2 100644 --- a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.html +++ b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.html @@ -1,49 +1,9 @@ - - - - - {{ field.name }} - - - - - {{ value.origin }} - - - - - - - - - - 属性 - 值 - - - - - {{ field.name }} - {{ rowValues[i].origin + ' ' + (field.unit ? field.unit : '') }} - - - - - - -

{{ metrics }}

-
- - - 采集时间:{{ time | _date: 'HH:mm:ss' }} -
-
- - - - - - - - +
diff --git a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.spec.ts b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.spec.ts index 7514537..599eaa4 100644 --- a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.spec.ts +++ b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.spec.ts @@ -8,8 +8,9 @@ describe('MonitorDataChartComponent', () => { beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [MonitorDataChartComponent] - }).compileComponents(); + declarations: [ MonitorDataChartComponent ] + }) + .compileComponents(); }); beforeEach(() => { diff --git a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.ts b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.ts index 685a0af..c4f8831 100644 --- a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.ts +++ b/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.ts @@ -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 = 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; } } diff --git a/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.html b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.html new file mode 100644 index 0000000..1b680df --- /dev/null +++ b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.html @@ -0,0 +1,49 @@ + + + + + {{ field.name }} + + + + + {{ value.origin }} + + + + + + + + + + 属性 + 值 + + + + + {{ field.name }} + {{ rowValues[i].origin + ' ' + (field.unit ? field.unit : '') }} + + + + + + +

{{ metrics }}

+
+ + + 采集时间:{{ time | _date: 'HH:mm:ss' }} +
+
+ + + + + + + + diff --git a/web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.less b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.less similarity index 100% rename from web-app/src/app/routes/monitor/monitor-data-chart/monitor-data-chart.component.less rename to web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.less diff --git a/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.spec.ts b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.spec.ts new file mode 100644 index 0000000..8c10966 --- /dev/null +++ b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.spec.ts @@ -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; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [MonitorDataTableComponent] + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(MonitorDataTableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.ts b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.ts new file mode 100644 index 0000000..8e94994 --- /dev/null +++ b/web-app/src/app/routes/monitor/monitor-data-table/monitor-data-table.component.ts @@ -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(); + } + ); + } +} diff --git a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html index 10dd1d0..82e8ff7 100644 --- a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html +++ b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.html @@ -103,11 +103,28 @@ - 监控数据报告详情 + 监控实时数据详情
- + +
+
+
+ + + + 监控历史图表详情 + +
+
+
diff --git a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts index c11c05c..1fc126b 100644 --- a/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts +++ b/web-app/src/app/routes/monitor/monitor-detail/monitor-detail.component.ts @@ -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); } ); } diff --git a/web-app/src/app/routes/monitor/monitor.module.ts b/web-app/src/app/routes/monitor/monitor.module.ts index 8942e75..e96d33a 100644 --- a/web-app/src/app/routes/monitor/monitor.module.ts +++ b/web-app/src/app/routes/monitor/monitor.module.ts @@ -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> = [ MonitorEditComponent, MonitorListComponent, MonitorDetailComponent, + MonitorDataTableComponent, MonitorDataChartComponent ]; diff --git a/web-app/src/app/service/app-define.service.ts b/web-app/src/app/service/app-define.service.ts index 667157f..0be9c49 100644 --- a/web-app/src/app/service/app-define.service.ts +++ b/web-app/src/app/service/app-define.service.ts @@ -21,6 +21,13 @@ export class AppDefineService { return this.http.get>(paramDefineUri); } + public getAppDefine(app: string | undefined | null): Observable> { + if (app === null || app === undefined) { + console.log('getAppDefine app can not null'); + } + return this.http.get>(`/apps/${app}/define`); + } + public getAppHierarchy(): Observable> { let httpParams = new HttpParams().append('lang', 'zh-CN'); const options = { params: httpParams }; diff --git a/web-app/src/app/service/local-storage.service.ts b/web-app/src/app/service/local-storage.service.ts index fadaed0..956364e 100644 --- a/web-app/src/app/service/local-storage.service.ts +++ b/web-app/src/app/service/local-storage.service.ts @@ -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() { diff --git a/web-app/src/app/service/monitor.service.ts b/web-app/src/app/service/monitor.service.ts index 4dfe20f..af68c60 100644 --- a/web-app/src/app/service/monitor.service.ts +++ b/web-app/src/app/service/monitor.service.ts @@ -107,6 +107,24 @@ export class MonitorService { return this.http.get>(`/monitor/${monitorId}/metrics/${metrics}`); } + public getMonitorMetricHistoryData( + monitorId: number, + app: string, + metrics: string, + metric: string, + history: string, + interval: boolean + ): Observable> { + let metricFull = `${app}.${metrics}.${metric}`; + let httpParams = new HttpParams(); + httpParams = httpParams.appendAll({ + history: history, + interval: interval + }); + const options = { params: httpParams }; + return this.http.get>(`/monitor/${monitorId}/metric/${metricFull}`, options); + } + public getAppsMonitorSummary(): Observable> { return this.http.get>(summary_uri); }