feat: 添加自定监控
This commit is contained in:
parent
85facc5364
commit
5c69806d00
|
@ -18,6 +18,7 @@ import io.metersphere.dto.LogDetailDTO;
|
|||
import io.metersphere.performance.base.*;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
import io.metersphere.performance.dto.Monitor;
|
||||
import io.metersphere.performance.service.MetricQueryService;
|
||||
import io.metersphere.performance.service.PerformanceReportService;
|
||||
import io.metersphere.performance.service.PerformanceTestService;
|
||||
|
@ -239,7 +240,7 @@ public class ShareController {
|
|||
}
|
||||
|
||||
@GetMapping("/metric/query/resource/{shareId}/{id}")
|
||||
public List<String> queryReportResource(@PathVariable String shareId, @PathVariable("id") String reportId) {
|
||||
public List<Monitor> queryReportResource(@PathVariable String shareId, @PathVariable("id") String reportId) {
|
||||
return metricService.queryReportResource(reportId);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package io.metersphere.performance.controller;
|
||||
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
import io.metersphere.performance.dto.Monitor;
|
||||
import io.metersphere.performance.service.MetricQueryService;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
@ -20,7 +21,7 @@ public class MetricQueryController {
|
|||
}
|
||||
|
||||
@GetMapping("/query/resource/{id}")
|
||||
public List<String> queryReportResource(@PathVariable("id") String reportId) {
|
||||
public List<Monitor> queryReportResource(@PathVariable("id") String reportId) {
|
||||
return metricService.queryReportResource(reportId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ package io.metersphere.performance.dto;
|
|||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class Monitor {
|
||||
private String name;
|
||||
private String environmentId;
|
||||
private String environmentName;
|
||||
private String ip;
|
||||
private Integer port;
|
||||
private String description;
|
||||
private String monitorStatus;
|
||||
private List<MonitorItem> monitorConfig;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package io.metersphere.performance.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MonitorItem {
|
||||
private String value; // 表达式
|
||||
private String name; // 监控项
|
||||
}
|
|
@ -4,7 +4,6 @@ package io.metersphere.performance.service;
|
|||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.nacos.client.utils.StringUtils;
|
||||
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
import io.metersphere.base.mapper.LoadTestReportMapper;
|
||||
|
@ -21,9 +20,11 @@ import io.metersphere.performance.controller.request.MetricQuery;
|
|||
import io.metersphere.performance.controller.request.MetricRequest;
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
import io.metersphere.performance.dto.Monitor;
|
||||
import io.metersphere.performance.dto.MonitorItem;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import io.metersphere.service.TestResourceService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
@ -156,7 +157,7 @@ public class MetricQueryService {
|
|||
}
|
||||
|
||||
public List<MetricData> queryMetric(String reportId) {
|
||||
List<String> instances = new ArrayList<>();
|
||||
List<Monitor> instances = new ArrayList<>();
|
||||
LoadTestReportWithBLOBs report = loadTestReportMapper.selectByPrimaryKey(reportId);
|
||||
String poolId = report.getTestResourcePoolId();
|
||||
List<TestResource> resourceList = testResourceService.getTestResourceList(poolId);
|
||||
|
@ -166,7 +167,10 @@ public class MetricQueryService {
|
|||
NodeDTO dto = JSON.parseObject(resource.getConfiguration(), NodeDTO.class);
|
||||
if (StringUtils.isNotBlank(dto.getIp())) {
|
||||
int port = dto.getMonitorPort() == null ? 9100 : dto.getMonitorPort();
|
||||
instances.add(dto.getIp() + ":" + port);
|
||||
Monitor e = new Monitor();
|
||||
e.setIp(dto.getIp());
|
||||
e.setPort(port);
|
||||
instances.add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -179,11 +183,14 @@ public class MetricQueryService {
|
|||
List<MetricDataRequest> list = new ArrayList<>();
|
||||
// 加入高级设置中的监控配置
|
||||
for (int i = 0; i < monitorParams.size(); i++) {
|
||||
Monitor monitor = monitorParams.getObject(i, Monitor.class);
|
||||
String instance = monitor.getIp() + ":" + monitor.getPort();
|
||||
if (!instances.contains(instance)) {
|
||||
instances.add(instance);
|
||||
}
|
||||
JSONObject o = monitorParams.getJSONObject(i);
|
||||
Monitor monitor = new Monitor();
|
||||
monitor.setIp(o.getString("ip"));
|
||||
monitor.setName(o.getString("name"));
|
||||
monitor.setPort(o.getInteger("port"));
|
||||
monitor.setDescription(o.getString("description"));
|
||||
monitor.setMonitorConfig(JSONObject.parseArray(o.getString("monitorConfig"), MonitorItem.class));
|
||||
instances.add(monitor);
|
||||
}
|
||||
|
||||
instances.forEach(instance -> {
|
||||
|
@ -203,38 +210,55 @@ public class MetricQueryService {
|
|||
return queryMetricData(metricRequest);
|
||||
}
|
||||
|
||||
private void getRequest(String instance, List<MetricDataRequest> list) {
|
||||
Map<String, String> map = MetricQuery.getMetricQueryMap();
|
||||
Set<String> set = map.keySet();
|
||||
set.forEach(s -> {
|
||||
MetricDataRequest request = new MetricDataRequest();
|
||||
String promQL = map.get(s);
|
||||
request.setPromQL(promQL);
|
||||
request.setSeriesName(s);
|
||||
request.setInstance(instance);
|
||||
list.add(request);
|
||||
});
|
||||
private void getRequest(Monitor monitor, List<MetricDataRequest> list) {
|
||||
if (CollectionUtils.isNotEmpty(monitor.getMonitorConfig())) {
|
||||
monitor.getMonitorConfig().forEach(c -> {
|
||||
if (StringUtils.isBlank(c.getValue())) {
|
||||
return;
|
||||
}
|
||||
MetricDataRequest request = new MetricDataRequest();
|
||||
String promQL = c.getValue();
|
||||
request.setPromQL(promQL);
|
||||
request.setSeriesName(c.getName());
|
||||
request.setInstance(monitor.getIp() + ":" + monitor.getPort());
|
||||
list.add(request);
|
||||
});
|
||||
} else {
|
||||
Map<String, String> map = MetricQuery.getMetricQueryMap();
|
||||
Set<String> set = map.keySet();
|
||||
set.forEach(s -> {
|
||||
MetricDataRequest request = new MetricDataRequest();
|
||||
String promQL = map.get(s);
|
||||
request.setPromQL(promQL);
|
||||
request.setSeriesName(s);
|
||||
request.setInstance(monitor.getIp() + ":" + monitor.getPort());
|
||||
list.add(request);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> queryReportResource(String reportId) {
|
||||
List<String> result = new ArrayList<>();
|
||||
public List<Monitor> queryReportResource(String reportId) {
|
||||
List<Monitor> result = new ArrayList<>();
|
||||
List<String> resourceIdAndIndexes = extLoadTestReportMapper.selectResourceId(reportId);
|
||||
resourceIdAndIndexes.forEach(resourceIdAndIndex -> {
|
||||
String[] split = org.apache.commons.lang3.StringUtils.split(resourceIdAndIndex, "_");
|
||||
String[] split = StringUtils.split(resourceIdAndIndex, "_");
|
||||
String resourceId = split[0];
|
||||
TestResource testResource = testResourceService.getTestResource(resourceId);
|
||||
if (testResource == null) {
|
||||
return;
|
||||
}
|
||||
String configuration = testResource.getConfiguration();
|
||||
if (org.apache.commons.lang3.StringUtils.isBlank(configuration)) {
|
||||
if (StringUtils.isBlank(configuration)) {
|
||||
return;
|
||||
}
|
||||
NodeDTO dto = JSON.parseObject(configuration, NodeDTO.class);
|
||||
if (StringUtils.isNotBlank(dto.getIp())) {
|
||||
Integer monitorPort = dto.getMonitorPort();
|
||||
int port = monitorPort == null ? 9100 : monitorPort;
|
||||
result.add(dto.getIp() + ":" + port);
|
||||
Monitor monitor = new Monitor();
|
||||
monitor.setIp(dto.getIp());
|
||||
monitor.setPort(port);
|
||||
result.add(monitor);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -247,11 +271,14 @@ public class MetricQueryService {
|
|||
}
|
||||
|
||||
for (int i = 0; i < monitorParams.size(); i++) {
|
||||
Monitor monitor = monitorParams.getObject(i, Monitor.class);
|
||||
String instance = monitor.getIp() + ":" + monitor.getPort();
|
||||
if (!result.contains(instance)) {
|
||||
result.add(instance);
|
||||
}
|
||||
JSONObject o = monitorParams.getJSONObject(i);
|
||||
Monitor monitor = new Monitor();
|
||||
monitor.setIp(o.getString("ip"));
|
||||
monitor.setName(o.getString("name"));
|
||||
monitor.setPort(o.getInteger("port"));
|
||||
monitor.setDescription(o.getString("description"));
|
||||
monitor.setMonitorConfig(JSONObject.parseArray(o.getString("monitorConfig"), MonitorItem.class));
|
||||
result.add(monitor);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -6,6 +6,7 @@ import io.metersphere.dto.LogDetailDTO;
|
|||
import io.metersphere.performance.base.*;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
import io.metersphere.performance.dto.Monitor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
|
@ -42,7 +43,7 @@ public class TestPlanLoadCaseDTO extends TestPlanLoadCase {
|
|||
private List<Errors> reportErrors;
|
||||
private List<ErrorsTop5> reportErrorsTop5;
|
||||
private List<LogDetailDTO> reportLogResource;
|
||||
private List<String> reportResource;
|
||||
private List<Monitor> reportResource;
|
||||
private List<MetricData> metricData;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ import io.metersphere.notice.service.NoticeSendService;
|
|||
import io.metersphere.performance.base.*;
|
||||
import io.metersphere.performance.dto.LoadTestExportJmx;
|
||||
import io.metersphere.performance.dto.MetricData;
|
||||
import io.metersphere.performance.dto.Monitor;
|
||||
import io.metersphere.performance.request.RunTestPlanRequest;
|
||||
import io.metersphere.performance.service.MetricQueryService;
|
||||
import io.metersphere.performance.service.PerformanceReportService;
|
||||
|
@ -1573,7 +1574,7 @@ public class TestPlanService {
|
|||
response.setReportLogResource(reportLogResource);
|
||||
// performanceReportService.getReportLogs(reportId, resourceId);
|
||||
|
||||
List<String> reportResource = metricQueryService.queryReportResource(reportId);
|
||||
List<Monitor> reportResource = metricQueryService.queryReportResource(reportId);
|
||||
response.setReportResource(reportResource);
|
||||
List<MetricData> metricData = metricQueryService.queryMetric(reportId);
|
||||
response.setMetricData(metricData);
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit a6a66f87a57346cdd7da22086bac5e82a7e47bdb
|
||||
Subproject commit 6e2b1d3d7d79f985e6edf81eb593670b8da87465
|
|
@ -6,10 +6,10 @@
|
|||
<el-select v-model="currentInstance" placeholder="" size="small" style="width: 100%"
|
||||
@change="handleChecked(currentInstance)">
|
||||
<el-option
|
||||
v-for="item in instances"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item">
|
||||
v-for="item in instances"
|
||||
:key="item.ip+item.port"
|
||||
:value="item.ip+':'+item.port">
|
||||
{{ item.ip }} {{ item.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
@ -35,47 +35,47 @@
|
|||
<el-row>
|
||||
<el-col :offset="2" :span="20">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
:data="tableData"
|
||||
stripe
|
||||
border
|
||||
style="width: 100%">
|
||||
<el-table-column label="Label" align="center">
|
||||
<el-table-column
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
prop="label"
|
||||
label="Label"
|
||||
sortable>
|
||||
</el-table-column>
|
||||
</el-table-column>
|
||||
<el-table-column label="Aggregate" align="center">
|
||||
<el-table-column
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
prop="avg"
|
||||
label="Avg."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
prop="min"
|
||||
label="Min."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
<el-table-column
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
prop="max"
|
||||
label="Max."
|
||||
width="100"
|
||||
sortable
|
||||
/>
|
||||
</el-table-column>
|
||||
<el-table-column label="Range" align="center">
|
||||
<el-table-column
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
prop="startTime"
|
||||
label="Start"
|
||||
width="160"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
prop="endTime"
|
||||
label="End"
|
||||
width="160"
|
||||
/>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
@ -97,6 +97,14 @@ import {
|
|||
} from "@/network/load-test";
|
||||
|
||||
const color = ['#60acfc', '#32d3eb', '#5bc49f', '#feb64d', '#ff7c7c', '#9287e7', '#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3'];
|
||||
const checkList = ['CPU', 'Memory', 'Disk', 'Network In', 'Network Out'];
|
||||
const checkOptions = [
|
||||
{key: 'cpu', label: 'CPU'},
|
||||
{key: 'memory', label: 'Memory'},
|
||||
{key: 'disk', label: 'Disk'},
|
||||
{key: 'netIn', label: 'Network In'},
|
||||
{key: 'netOut', label: 'Network Out'}
|
||||
];
|
||||
|
||||
export default {
|
||||
name: "MonitorCard",
|
||||
|
@ -113,14 +121,8 @@ export default {
|
|||
instances: [],
|
||||
data: [],
|
||||
tableData: [],
|
||||
checkList: ['CPU', 'Memory', 'Disk', 'Network In', 'Network Out'],
|
||||
checkOptions: [
|
||||
{key: 'cpu', label: 'CPU'},
|
||||
{key: 'memory', label: 'Memory'},
|
||||
{key: 'disk', label: 'Disk'},
|
||||
{key: 'netIn', label: 'Network In'},
|
||||
{key: 'netOut', label: 'Network Out'}
|
||||
],
|
||||
checkList: checkList,
|
||||
checkOptions: checkOptions,
|
||||
baseOption: {
|
||||
color: color,
|
||||
grid: {
|
||||
|
@ -175,14 +177,14 @@ export default {
|
|||
// this.init = true;
|
||||
if (this.planReportTemplate) {
|
||||
this.instances = this.planReportTemplate.reportResource;
|
||||
this.currentInstance = this.instances[0];
|
||||
this.currentInstance = this.instances[0].ip + ":" + this.instances[0].port;
|
||||
this.data = this.planReportTemplate.metricData;
|
||||
this.totalOption = this.getOption(this.currentInstance);
|
||||
} else if (this.isShare) {
|
||||
getSharePerformanceMetricQueryResource(this.shareId, this.id).then(response => {
|
||||
this.instances = response.data.data;
|
||||
if (!this.currentInstance) {
|
||||
this.currentInstance = this.instances[0];
|
||||
this.currentInstance = this.instances[0].ip + ":" + this.instances[0].port;
|
||||
}
|
||||
getSharePerformanceMetricQuery(this.shareId, this.id).then(result => {
|
||||
if (result) {
|
||||
|
@ -196,7 +198,7 @@ export default {
|
|||
getPerformanceMetricQueryResource(this.id).then(response => {
|
||||
this.instances = response.data.data;
|
||||
if (!this.currentInstance) {
|
||||
this.currentInstance = this.instances[0];
|
||||
this.currentInstance = this.instances[0].ip + ":" + this.instances[0].port;
|
||||
}
|
||||
getPerformanceMetricQuery(this.id).then(result => {
|
||||
if (result) {
|
||||
|
@ -211,6 +213,18 @@ export default {
|
|||
}
|
||||
},
|
||||
handleChecked(id) {
|
||||
let curr = this.instances.filter(instance => id === instance.ip + ":" + instance.port)[0];
|
||||
if (curr.monitorConfig) {
|
||||
this.checkList = [];
|
||||
this.checkOptions = curr.monitorConfig.filter(mc => mc.value && mc.name)
|
||||
.map(mc => {
|
||||
this.checkList.push(mc.name);
|
||||
return {key: mc.name, label: mc.name,};
|
||||
});
|
||||
} else {
|
||||
this.checkOptions = checkOptions;
|
||||
this.checkList = checkList;
|
||||
}
|
||||
this.totalOption = {};
|
||||
this.$nextTick(() => {
|
||||
this.totalOption = this.getOption(id);
|
||||
|
|
|
@ -8,27 +8,36 @@
|
|||
:destroy-on-close="true"
|
||||
v-loading="result.loading"
|
||||
>
|
||||
<el-form :model="form" label-position="right" label-width="80px" size="small" :rules="rule" ref="monitorForm">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<h4 style="margin-left: 80px;">监控配置</h4>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="IP" prop="ip">
|
||||
<el-input v-model="form.ip" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="Port" prop="port">
|
||||
<el-input-number v-model="form.port" :min="1" :max="65535"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="height: 50vh;overflow-y: auto;">
|
||||
<el-form :model="form" label-position="right" label-width="80px" size="small" :rules="rule" ref="monitorForm">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="form.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<h4 style="margin-left: 80px;">监控配置</h4>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="IP" prop="ip">
|
||||
<el-input v-model="form.ip" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="Port" prop="port">
|
||||
<el-input-number v-model="form.port" :min="1" :max="65535"/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="描述" prop="description">
|
||||
<el-input v-model="form.description" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<h4 style="margin-left: 80px;">监控项</h4>
|
||||
<el-row>
|
||||
<el-col :span="20" :offset="2">
|
||||
<monitor-key-value key-placeholder="Label" value-placeholder="promQL" :items="monitorList"
|
||||
:suggestions="metricSuggestions"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<template v-slot:footer>
|
||||
<ms-dialog-footer
|
||||
|
@ -47,11 +56,11 @@
|
|||
<script>
|
||||
|
||||
import MsDialogFooter from "@/business/components/common/components/MsDialogFooter";
|
||||
import {CONFIG_TYPE} from "@/common/js/constants";
|
||||
import MonitorKeyValue from "@/business/components/performance/test/components/MonitorKeyValue";
|
||||
|
||||
export default {
|
||||
name: "EditMonitor",
|
||||
components: {MsDialogFooter},
|
||||
components: {MonitorKeyValue, MsDialogFooter},
|
||||
props: {
|
||||
testId: String,
|
||||
list: Array,
|
||||
|
@ -67,6 +76,8 @@ export default {
|
|||
port: {required: true, message: "port必填", trigger: 'blur'},
|
||||
},
|
||||
index: '',
|
||||
monitorList: [],
|
||||
metricSuggestions: [{value: 'cpu'}, {value: 'memory'}, {value: 'disk'}, {value: 'netIn'}, {value: 'netOut'}]
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -75,6 +86,9 @@ export default {
|
|||
this.dialogVisible = true;
|
||||
if (data) {
|
||||
const copy = JSON.parse(JSON.stringify(data));
|
||||
if (copy.monitorConfig) {
|
||||
this.monitorList = JSON.parse(copy.monitorConfig);
|
||||
}
|
||||
this.form = copy;
|
||||
}
|
||||
if (index !== '' && index !== undefined) {
|
||||
|
@ -88,6 +102,7 @@ export default {
|
|||
update() {
|
||||
this.$refs.monitorForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.form.monitorConfig = JSON.stringify(this.monitorList);
|
||||
this.list.splice(this.index, 1, this.form);
|
||||
this.$emit("update:list", this.list);
|
||||
this.dialogVisible = false;
|
||||
|
@ -99,6 +114,7 @@ export default {
|
|||
create() {
|
||||
this.$refs.monitorForm.validate(valid => {
|
||||
if (valid) {
|
||||
this.form.monitorConfig = JSON.stringify(this.monitorList);
|
||||
// this.form.monitorStatus = CONFIG_TYPE.NOT;
|
||||
this.list.push(this.form);
|
||||
this.$emit("update:list", this.list);
|
||||
|
|
|
@ -0,0 +1,155 @@
|
|||
<template>
|
||||
<div>
|
||||
<span class="kv-description" v-if="description">
|
||||
{{ description }}
|
||||
</span>
|
||||
<div class="kv-row" v-for="(item, index) in items" :key="index">
|
||||
<el-row type="flex" :gutter="20" justify="space-between" align="middle">
|
||||
<el-col>
|
||||
<el-input v-if="!suggestions" :disabled="isReadOnly" v-model="item.name" size="small" maxlength="200"
|
||||
@change="changeKey(item)"
|
||||
:placeholder="keyText" show-word-limit/>
|
||||
<el-autocomplete :disabled="isReadOnly" :maxlength="200" v-if="suggestions" v-model="item.name" size="small"
|
||||
:fetch-suggestions="querySearch" :placeholder="keyText"
|
||||
@select="changeKey(item)"
|
||||
show-word-limit/>
|
||||
|
||||
</el-col>
|
||||
|
||||
<el-col>
|
||||
<el-input :disabled="isReadOnly" v-model="item.value" size="small" @change="change"
|
||||
:placeholder="valueText" show-word-limit/>
|
||||
</el-col>
|
||||
<el-col class="kv-delete">
|
||||
<el-button size="mini" class="el-icon-delete-solid" circle @click="remove(index)"
|
||||
:disabled="isDisable(index) || isReadOnly"/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
const CPU_QL = "100 - (avg by (instance) (irate(node_cpu_seconds_total{instance='%1$s', mode='idle'}[1m])) * 100)";
|
||||
const MEMORY_QL = "(node_memory_MemTotal_bytes{instance='%1$s'} - node_memory_MemAvailable_bytes{instance='%1$s'}) / node_memory_MemTotal_bytes{instance='%1$s'} * 100";
|
||||
const DISK_QL = "100 - node_filesystem_free_bytes{instance='%1$s'} / node_filesystem_size_bytes{instance='%1$s'} * 100";
|
||||
const NET_IN_QL = "sum by (instance) (irate(node_network_receive_bytes_total{instance='%1$s',device!~'bond.*?|lo'}[1m])/1024)";
|
||||
const NET_OUT_QL = "sum by (instance) (irate(node_network_transmit_bytes_total{instance='%1$s',device!~'bond.*?|lo'}[1m])/1024)";
|
||||
|
||||
import {KeyValue} from "@/business/components/api/test/model/ScenarioModel";
|
||||
|
||||
export default {
|
||||
name: "MonitorKeyValue",
|
||||
|
||||
props: {
|
||||
keyPlaceholder: String,
|
||||
valuePlaceholder: String,
|
||||
description: String,
|
||||
items: Array,
|
||||
isReadOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
suggestions: Array
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
keyText() {
|
||||
return this.keyPlaceholder || this.$t("api_test.key");
|
||||
},
|
||||
valueText() {
|
||||
return this.valuePlaceholder || this.$t("api_test.value");
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
remove: function (index) {
|
||||
// 移除整行输入控件及内容
|
||||
this.items.splice(index, 1);
|
||||
this.$emit('change', this.items);
|
||||
},
|
||||
change: function () {
|
||||
let isNeedCreate = true;
|
||||
let removeIndex = -1;
|
||||
this.items.forEach((item, index) => {
|
||||
if (!item.name && !item.value) {
|
||||
// 多余的空行
|
||||
if (index !== this.items.length - 1) {
|
||||
removeIndex = index;
|
||||
}
|
||||
// 没有空行,需要创建空行
|
||||
isNeedCreate = false;
|
||||
}
|
||||
});
|
||||
if (isNeedCreate) {
|
||||
this.items.push(new KeyValue({enable: true}));
|
||||
}
|
||||
this.$emit('change', this.items);
|
||||
// TODO 检查key重复
|
||||
},
|
||||
changeKey: function (curr) {
|
||||
// 填充值
|
||||
if (curr.name === 'cpu') {
|
||||
curr.value = CPU_QL;
|
||||
}
|
||||
if (curr.name === 'memory') {
|
||||
curr.value = MEMORY_QL;
|
||||
}
|
||||
if (curr.name === 'disk') {
|
||||
curr.value = DISK_QL;
|
||||
}
|
||||
if (curr.name === 'netIn') {
|
||||
curr.value = NET_IN_QL;
|
||||
}
|
||||
if (curr.name === 'netOut') {
|
||||
curr.value = NET_OUT_QL;
|
||||
}
|
||||
this.change();
|
||||
},
|
||||
isDisable: function (index) {
|
||||
return this.items.length - 1 === index;
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
let suggestions = this.suggestions;
|
||||
let results = queryString ? suggestions.filter(this.createFilter(queryString)) : suggestions;
|
||||
cb(results);
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (restaurant) => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
|
||||
};
|
||||
},
|
||||
},
|
||||
created() {
|
||||
if (this.items.length === 0 || this.items[this.items.length - 1].name) {
|
||||
this.items.push(new KeyValue({enable: true}));
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.kv-description {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.kv-row {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.kv-checkbox {
|
||||
width: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.kv-delete {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.el-autocomplete {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue