feat:alertMessage 添加 Trouble shooting按钮

This commit is contained in:
zhangyu
2021-09-09 16:00:37 +08:00
parent 60099d66ac
commit d75ae40c19
6 changed files with 219 additions and 10 deletions

View File

@@ -245,6 +245,10 @@ export default {
}, },
closeDialog () { closeDialog () {
this.silenceBoxShow = false this.silenceBoxShow = false
},
showText (row) {
this.dialogShowText = true
this.dialogText = row.alertRule.trbShot
} }
}, },
watch: { watch: {

View File

@@ -30,16 +30,18 @@
v-for="item in searchMetrics" v-for="item in searchMetrics"
:key="item.value" :key="item.value"
:label="item.label" :label="item.label"
:value="item.value"></el-option> :value="item.value"
style="width: 312px"></el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<!--severity--> <!--severity-->
<el-form-item :label="$t('alert.severity')" class="severity-box half-form-item" prop="severityId"> <el-form-item :label="$t('alert.severity')" class="severity-box half-form-item" prop="severityId">
<el-select id="alert-box-input-severity" v-model="editAlertRule.severityId" class="right-box__select" placeholder="" popper-class="prevent-clickoutside" size="small"> <el-select id="alert-box-input-severity" v-model="editAlertRule.severityId" class="right-box__select" placeholder="" popper-class="prevent-clickoutside" size="small">
<el-option v-for="item in severityData" :id="'alert-severity-'+item.value" :key="item.id" :label="item.name" :value="item.id"> <el-option v-for="item in severityData" :id="'alert-severity-'+item.value" :key="item.id" :label="item.name" :value="item.id" style="width: 312px">
<span> <div style="display: flex;justify-content: space-between;padding: 5px;">
<i :style="{color:item.color,'font-size':'12px'}" class="nz-icon nz-icon-circle"></i> {{item.name}} <div><i :style="{color:item.color,'font-size':'12px'}" class="nz-icon nz-icon-circle"></i> {{item.name}}</div>
</span> <div class="severity-item">{{item.remark}}</div>
</div>
</el-option> </el-option>
</el-select> </el-select>
<i v-if="editAlertRule.severityId" :style="{color:severityData.length > 0 && severityData.find(severity => severity.id === editAlertRule.severityId).color,'font-size':'12px'}" class="nz-icon nz-icon-circle severity-circle"></i> <i v-if="editAlertRule.severityId" :style="{color:severityData.length > 0 && severityData.find(severity => severity.id === editAlertRule.severityId).color,'font-size':'12px'}" class="nz-icon nz-icon-circle severity-circle"></i>
@@ -127,10 +129,12 @@
size="small" size="small"
> >
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.on')" :label="$t('dashboard.panel.chartForm.lockList.on')"
:value="1"> :value="1">
</el-option> </el-option>
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.off')" :label="$t('dashboard.panel.chartForm.lockList.off')"
:value="0"> :value="0">
</el-option> </el-option>
@@ -161,10 +165,12 @@
size="small" size="small"
> >
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.on')" :label="$t('dashboard.panel.chartForm.lockList.on')"
:value="1"> :value="1">
</el-option> </el-option>
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.off')" :label="$t('dashboard.panel.chartForm.lockList.off')"
:value="0"> :value="0">
</el-option> </el-option>
@@ -182,10 +188,12 @@
size="small" size="small"
> >
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.on')" :label="$t('dashboard.panel.chartForm.lockList.on')"
:value="1"> :value="1">
</el-option> </el-option>
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.off')" :label="$t('dashboard.panel.chartForm.lockList.off')"
:value="0"> :value="0">
</el-option> </el-option>
@@ -249,10 +257,12 @@
@change="receiverAndNotifyValidate" @change="receiverAndNotifyValidate"
> >
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.on')" :label="$t('dashboard.panel.chartForm.lockList.on')"
:value="1"> :value="1">
</el-option> </el-option>
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.off')" :label="$t('dashboard.panel.chartForm.lockList.off')"
:value="0"> :value="0">
</el-option> </el-option>
@@ -271,10 +281,12 @@
@change="receiverAndNotifyValidate" @change="receiverAndNotifyValidate"
> >
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.on')" :label="$t('dashboard.panel.chartForm.lockList.on')"
:value="1"> :value="1">
</el-option> </el-option>
<el-option <el-option
style="width: 312px"
:label="$t('dashboard.panel.chartForm.lockList.off')" :label="$t('dashboard.panel.chartForm.lockList.off')"
:value="0"> :value="0">
</el-option> </el-option>
@@ -689,4 +701,8 @@ export default {
/deep/ .el-form-item__content .el-input-group{ /deep/ .el-form-item__content .el-input-group{
vertical-align: middle; vertical-align: middle;
} }
.severity-item{
color: #999999;
font-size: 12px;
}
</style> </style>

View File

@@ -115,6 +115,7 @@
</div> </div>
<el-dropdown-menu slot="dropdown"> <el-dropdown-menu slot="dropdown">
<el-dropdown-item v-has="'alertMessage_expired'" :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item> <el-dropdown-item v-has="'alertMessage_expired'" :command="['delete', scope.row]"><i class="nz-icon nz-icon-delete"></i><span class="operation-dropdown-text">{{$t('overall.delete')}}</span></el-dropdown-item>
<el-dropdown-item :command="['showText', scope.row]"><i class="nz-icon nz-icon-text1"></i><span class="operation-dropdown-text">{{$t('alert.config.trbShot')}}</span></el-dropdown-item>
<el-dropdown-item v-has="'alertSilence_add'" :command="['fastSilence', scope.row, 'alertMessage']"><i class="nz-icon nz-icon-fast-silence"></i><span class="operation-dropdown-text">{{$t('overall.silenceAlert')}}</span></el-dropdown-item> <el-dropdown-item v-has="'alertSilence_add'" :command="['fastSilence', scope.row, 'alertMessage']"><i class="nz-icon nz-icon-fast-silence"></i><span class="operation-dropdown-text">{{$t('overall.silenceAlert')}}</span></el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>

View File

@@ -34,6 +34,7 @@
:table-data="tableData" :table-data="tableData"
@del="del" @del="del"
@edit="edit" @edit="edit"
@showText="showText"
@orderBy="tableDataSort" @orderBy="tableDataSort"
@queryMessage='queryMessage' @queryMessage='queryMessage'
@reload="getTableData" @reload="getTableData"
@@ -96,6 +97,21 @@
</div> </div>
<chart ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart> <chart ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart>
</el-dialog> </el-dialog>
<!--全屏-->
<el-dialog class="nz-dialog table-chart-dialog" :title="$t('alert.config.trbShot')"
:visible.sync="dialogShowText"
width="96%" @close="dialogShowText = false" :modal-append-to-body="false">
<div slot="title">
<span class="nz-dialog-title">{{$t('alert.config.trbShot')}}</span>
</div>
<div class="rich-text-screen-container" >
<div id="chartScreenContainer" ref="chartScreenContainer" class="text-content" >
<el-scrollbar style="height: 100%;" class="el-scrollbar-normal">
<div style="height: 100%;" v-html="dialogText" ></div>
</el-scrollbar>
</div>
</div>
</el-dialog>
<transition name="right-box"><alert-silence-box v-if='silenceBoxShow' :alert-silence="objectSilence" @close="closeSilenceBox"></alert-silence-box> <transition name="right-box"><alert-silence-box v-if='silenceBoxShow' :alert-silence="objectSilence" @close="closeSilenceBox"></alert-silence-box>
</transition> </transition>
</div> </div>
@@ -111,8 +127,9 @@ import nzDataList from '@/components/common/table/nzDataList'
import dataListMixin from '@/components/common/mixin/dataList' import dataListMixin from '@/components/common/mixin/dataList'
import chartDataFormat from '@/components/charts/chartDataFormat' import chartDataFormat from '@/components/charts/chartDataFormat'
import chart from '@/components/page/dashboard/overview/chart' import chart from '@/components/page/dashboard/overview/chart'
import { alertMessage as alertMessageConstant } from '@/components/common/js/constants' import { alertMessage as alertMessageConstant, fromRoute } from '@/components/common/js/constants'
import alertSilenceBox from '@/components/common/rightBox/alertSilenceBox' import alertSilenceBox from '@/components/common/rightBox/alertSilenceBox'
import logsTempData from '@/components/charts/logsTempData'
export default { export default {
name: 'alertMessage', name: 'alertMessage',
components: { components: {
@@ -126,8 +143,11 @@ export default {
mixins: [dataListMixin], mixins: [dataListMixin],
data () { data () {
return { return {
chartLoading: false,
stateOptions: alertMessageConstant.states, stateOptions: alertMessageConstant.states,
state: '1', state: '1',
dialogShowText: false,
dialogText: '',
url: 'alert/message', url: 'alert/message',
// 导出相关 // 导出相关
importBox: { show: false, title: this.$t('overall.exportExcel') }, importBox: { show: false, title: this.$t('overall.exportExcel') },
@@ -198,7 +218,9 @@ export default {
}, },
requestIndex: 0, requestIndex: 0,
viewAssetState: false, viewAssetState: false,
nowTime: '' nowTime: '',
logData: [],
resultType: ''
} }
}, },
computed: { computed: {
@@ -288,7 +310,7 @@ export default {
this.graphShow = true this.graphShow = true
this.$nextTick(() => { this.$nextTick(() => {
this.searchTimeDialog = [bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000), bus.computeTimezoneTime(new Date().getTime())] this.searchTimeDialog = [bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000), bus.computeTimezoneTime(new Date().getTime())]
this.queryChartDate() this.queryDate()
}) })
}) })
}, },
@@ -298,6 +320,17 @@ export default {
} }
this.$refs.dataList.showBottomBox(alertMessage, alertRule) this.$refs.dataList.showBottomBox(alertMessage, alertRule)
}, },
queryDate () {
this.chartLoading = true
if (this.currentMsg.alertRule.type === 1) {
this.resultType = 'matrix'
this.$nextTick(() => {
this.queryChartDate()
})
} else if (this.currentMsg.alertRule.type === 2) {
this.queryLogData(1000)
}
},
queryChartDate () { queryChartDate () {
const $temp = this const $temp = this
const start = this.searchTimeDialog[0] ? this.searchTimeDialog[0] : bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000) const start = this.searchTimeDialog[0] ? this.searchTimeDialog[0] : bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000)
@@ -322,6 +355,7 @@ export default {
this.legend = [] this.legend = []
this.chartDatas = [] this.chartDatas = []
axios.all(axiosArr).then(res => { axios.all(axiosArr).then(res => {
this.chartLoading = false
try { try {
res.forEach((response, promIndex) => { res.forEach((response, promIndex) => {
if (response.status === 200) { if (response.status === 200) {
@@ -397,14 +431,164 @@ export default {
this.$refs.messageChart.setLegend(this.legend) this.$refs.messageChart.setLegend(this.legend)
this.$refs.messageChart.setSeries(this.chartDatas) this.$refs.messageChart.setSeries(this.chartDatas)
this.$refs.messageChart.endLoading() this.$refs.messageChart.endLoading()
this.$refs.messageChart.resize()
}) })
} catch (err) { } catch (err) {
// this.$message.error(err) // this.$message.error(err)
this.$refs.messageChart.endLoading() this.$refs.messageChart.endLoading()
this.chartLoading = false
} }
}) })
} }
}, },
exportLog ({ limit, descending }) {
const start = this.searchTimeDialog[0] ? this.searchTimeDialog[0] : bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000)
const end = this.searchTimeDialog[1] ? this.searchTimeDialog[1] : bus.computeTimezoneTime(new Date().getTime())
const params = {
logql: this.expressions,
start: start,
end: end,
direction: descending ? 'backward' : 'forward',
limit
}
axios.get('/logs/loki/export', { responseType: 'blob', params: params }).then(res => {
if (window.navigator.msSaveOrOpenBlob) {
// 兼容ie11
const blobObject = new Blob([res.data])
window.navigator.msSaveOrOpenBlob(blobObject, 'log')
} else {
const url = URL.createObjectURL(new Blob([res.data]))
const a = document.createElement('a')
document.body.appendChild(a) // 此处增加了将创建的添加到body当中
a.href = url
a.download = 'log'
a.target = '_blank'
a.click()
a.remove() // 将a标签移除
}
}, error => {
const $self = this
const reader = new FileReader()
reader.onload = function (event) {
const responseText = reader.result
const exception = JSON.parse(responseText)
if (exception.message) {
$self.$message.error(exception.message)
} else {
console.error(error)
}
}
reader.readAsText(error.response.data)
})
},
queryLogData (limit) { // log的chart和table是一个请求
if (!limit) {
limit = 1000
}
const start = this.searchTimeDialog[0] ? this.searchTimeDialog[0] : bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000)
const end = this.searchTimeDialog[1] ? this.searchTimeDialog[1] : bus.computeTimezoneTime(new Date().getTime())
this.expressions = [this.currentMsg.alertRule.expr]
this.$get('/logs/loki/api/v1/query_range?format=1&query=' + this.currentMsg.alertRule.expr + '&start=' + this.$stringTimeParseToUnix(start) + '&end=' + this.$stringTimeParseToUnix(end) + '&limit=' + limit).then(res => {
console.log(res)
this.chartLoading = false
const logData = [res.data]
this.resultType = res.data.resultType
this.$nextTick(() => {
if (this.$refs.logDetail) {
this.$refs.logDetail.time = this.chartData.param.time
this.$refs.logDetail.wrapLines = this.chartData.param.wrapLines
this.$refs.logDetail.operations.descending = this.chartData.param.descending
}
// logData.forEach((item, index) => {
// item.result.forEach(result => {
// result.elements = this.expressions[index]
// })
// })
this.logData = logData
this.resultType === 'matrix' && this.loadLogGraph()
})
})
},
loadLogGraph () {
const graphData = this.logData.filter(l => l.resultType === 'matrix')
if (graphData && graphData.length > 0) {
this.$refs.messageChart.startLoading()
const queryExpression = []
let series = []
const legend = []
this.expressions.forEach((item, index) => {
if (item !== '') {
queryExpression.push(item)
}
})
this.logData.forEach((response, index) => {
if (response.resultType === 'matrix') {
const data = response.result
if (!data || data.length < 1) {
return
}
data.forEach((result, i) => {
const seriesItem = {
name: '',
symbol: 'emptyCircle', // 去掉点
symbolSize: [2, 2],
showSymbol: false,
smooth: 0.2, // 曲线变平滑
data: [],
lineStyle: {
width: 1,
opacity: 0.9
},
type: 'line'
}
seriesItem.data = result.values.map((item) => {
return [item[0] * 1000, item[1]]
})
let host = ''// up,
let alias = ''
if (result.metric && Object.keys(result.metric).length > 0) {
const metric = Object.keys(result.metric)
if (metric.__name__) {
host = `${metric.__name__}{`// up,
}
metric.forEach((tag, i) => {
if (tag !== '__name__') {
host += `${tag}="${result.metric[tag]}",`
}
})
if (host.endsWith(',')) {
host = host.substr(0, host.length - 1)
}
if (metric.__name__) {
host += '}'
}
// 处理legend别名
// alias = this.dealLegendAlias(host, this.chartData.elements[index].legend)
if (!alias || alias === '') {
alias = host
}
} else {
alias = queryExpression[index]
}
seriesItem.name = alias + '-' + index
series.push(seriesItem)
legend.push({ name: seriesItem.name, alias: alias, isGray: false })
})
}
})
this.$refs.messageChart.setLegend(legend)
this.$refs.messageChart.setRandomColors(series.length)
if (!series.length) {
series = ''
}
this.$refs.messageChart.setSeries(series)
this.defaultChartVisible = true
this.$nextTick(() => {
this.$refs.messageChart.endLoading()
this.$refs.messageChart.resize()
})
}
},
getTableData (state) { getTableData (state) {
if (state) { if (state) {
this.state = state this.state = state

View File

@@ -130,7 +130,7 @@
</el-collapse-item> </el-collapse-item>
</template> </template>
<!--log--> <!--log-->
<template v-else> <template v-else v-loading="chartLoading">
<el-collapse-item v-if="showTab.indexOf('1') > -1" name="1" title="Graph"> <el-collapse-item v-if="showTab.indexOf('1') > -1" name="1" title="Graph">
<div class="chart-room"> <div class="chart-room">
<chart ref="logChart" :unit="chartUnit"></chart> <chart ref="logChart" :unit="chartUnit"></chart>
@@ -326,6 +326,7 @@ export default {
}, },
data () { data () {
return { return {
chartLoading: false,
rightBox: { // 面板弹出框相关 rightBox: { // 面板弹出框相关
show: false show: false
}, },
@@ -466,6 +467,7 @@ export default {
}) })
}, },
queryLogData (limit) { // log的chart和table是一个请求 queryLogData (limit) { // log的chart和table是一个请求
this.chartLoading = true
if (!limit) { if (!limit) {
limit = this.$refs.logDetail ? this.$refs.logDetail.getLimit() : 1000 limit = this.$refs.logDetail ? this.$refs.logDetail.getLimit() : 1000
} }
@@ -481,6 +483,7 @@ export default {
this.saveDisabled = false this.saveDisabled = false
} }
axios.all(requestArr).then(res => { axios.all(requestArr).then(res => {
this.chartLoading = false
const errorRowIndex = [] const errorRowIndex = []
res.forEach((r, i) => { res.forEach((r, i) => {
if (typeof r === 'string') { if (typeof r === 'string') {
@@ -521,6 +524,7 @@ export default {
}) })
} }
}).catch(e => { }).catch(e => {
this.chartLoading = false
this.$message.error(this.$t('terminallog.statusItem.unknownError')) this.$message.error(this.$t('terminallog.statusItem.unknownError'))
}) })
} }

View File

@@ -173,7 +173,7 @@ export default {
this.option.yAxis.axisLabel.formatter = this.defaultYAxisFormatter this.option.yAxis.axisLabel.formatter = this.defaultYAxisFormatter
} }
} }
if (this.series) { if (this.series && this.series.length) {
this.$set(this.option, 'series', this.series) this.$set(this.option, 'series', this.series)
this.noData = false this.noData = false
this.chart.clear() this.chart.clear()