feat:bottom alertMessage 替换图表组件

This commit is contained in:
zhangyu
2021-12-23 14:15:22 +08:00
parent 3454dc76ce
commit 18051f644d
3 changed files with 73 additions and 216 deletions

View File

@@ -184,6 +184,9 @@ export default {
if (isTimeSeries(this.chartInfo.type)) { if (isTimeSeries(this.chartInfo.type)) {
query += `&nullType=${this.chartInfo.param.nullType || 'null'}` query += `&nullType=${this.chartInfo.param.nullType || 'null'}`
} }
if (element.filter) {
query += `&filter=${element.filter}`
}
// if (isChartPie(this.chartInfo.type)) { // if (isChartPie(this.chartInfo.type)) {
// query += `&statistics=${this.chartInfo.param.statistics || 'last'}` // query += `&statistics=${this.chartInfo.param.statistics || 'last'}`
// } // }

View File

@@ -47,36 +47,56 @@
<Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination> <Pagination ref="Pagination" :pageObj="pageObj" :tableId="tableId" @pageNo='pageNo' @pageSize='pageSize'></Pagination>
</template> </template>
</nz-bottom-data-list> </nz-bottom-data-list>
<el-dialog id="viewGraphDialog" <!-- <el-dialog id="viewGraphDialog"-->
:modal-append-to-body='false' <!-- :modal-append-to-body='false'-->
destroy-on-close <!-- destroy-on-close-->
:title="$t('overall.detail')" <!-- :title="$t('overall.detail')"-->
<!-- :visible.sync="graphShow"-->
<!-- class="line-chart-block-modal nz-dialog endpoint-dialog"-->
<!-- width="90%"-->
<!-- @close="dialogClose">-->
<!-- <el-popover-->
<!-- v-if="isError"-->
<!-- placement="top-start"-->
<!-- :close-delay=10-->
<!-- trigger="hover"-->
<!-- popper-class="chart-error-popper">-->
<!-- <div >{{errorContent}}</div>-->
<!-- <span slot="reference" class="panel-info-corner panel-info-corner&#45;&#45;error">-->
<!-- <i class="nz-icon nz-icon-warning fa-model" ></i>-->
<!-- <span class="panel-info-corner-inner"></span>-->
<!-- </span>-->
<!-- </el-popover>-->
<!-- <div slot="title">-->
<!-- {{$t("project.endpoint.dialogTitle")}}-->
<!-- <div class="float-right panel-calendar dialog-tool" style="display: flex">-->
<!-- <pick-time v-model="searchTime" :refresh-data-func="queryDate" :use-chart-unit="false" :use-refresh="false" style="height: 28px;"></pick-time>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div style="width: 100%;height: 100%" v-loading="chartLoading">-->
<!-- <chart v-if="resultType === 'matrix'" ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart>-->
<!-- <log-tab v-if="resultType === 'streamsFormat'" ref="logDetailScreen" :log-data="logData" :showSwitch="false" :tab-index="tabIndex" @exportLog="exportLog" @limitChange="queryLogData"></log-tab>-->
<!-- </div>-->
<!-- </el-dialog>-->
<el-dialog
id="viewGraphDialog"
v-if="graphShow"
:visible.sync="graphShow" :visible.sync="graphShow"
class="line-chart-block-modal nz-dialog endpoint-dialog" :show-close="false"
width="90%" class="nz-dialog chart-fullscreen"
@close="dialogClose"> destroy-on-close
<el-popover fullscreen
v-if="isError" :modal-append-to-body="false"
placement="top-start" >
:close-delay=10 <panel-chart
trigger="hover" :ref="'chart-fullscreen' + chartInfo.id"
popper-class="chart-error-popper"> :chart-info="chartInfo"
<div >{{errorContent}}</div> :from="fromRoute.alertMessage"
<span slot="reference" class="panel-info-corner panel-info-corner--error"> :filter="{}"
<i class="nz-icon nz-icon-warning fa-model" ></i> :is-fullscreen="true"
<span class="panel-info-corner-inner"></span> :time-range="searchTime"
</span> @showFullscreen="showFullscreen"
</el-popover> ></panel-chart>
<div slot="title">
{{$t("project.endpoint.dialogTitle")}}
<div class="float-right panel-calendar dialog-tool" style="display: flex">
<pick-time v-model="searchTime" :refresh-data-func="queryDate" :use-chart-unit="false" :use-refresh="false" style="height: 28px;"></pick-time>
</div>
</div>
<div style="width: 100%;height: 100%" v-loading="chartLoading">
<chart v-if="resultType === 'matrix'" ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart>
<log-tab v-if="resultType === 'streamsFormat'" ref="logDetailScreen" :log-data="logData" :showSwitch="false" :tab-index="tabIndex" @exportLog="exportLog" @limitChange="queryLogData"></log-tab>
</div>
</el-dialog> </el-dialog>
<el-dialog class="nz-dialog table-chart-dialog" :title="$t('alert.config.trbShot')" <el-dialog class="nz-dialog table-chart-dialog" :title="$t('alert.config.trbShot')"
:visible.sync="dialogShowText" :visible.sync="dialogShowText"
@@ -109,6 +129,10 @@ import chart from '@/components/page/dashboard/overview/chart'
import { alertMessage as alertMessageConstant, fromRoute } 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 detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin' import detailViewRightMixin from '@/components/common/mixin/detailViewRightMixin'
import panelChart from '@/components/chart/panelChart'
import lodash from 'lodash'
import lineData from '@/components/chart/defaultLineData'
import logData from '@/components/chart/defaultLogData'
export default { export default {
name: 'alertMessageTab', name: 'alertMessageTab',
@@ -117,7 +141,8 @@ export default {
nzBottomDataList, nzBottomDataList,
alertMessageTable, alertMessageTable,
alertSilenceBox, alertSilenceBox,
chart chart,
panelChart
}, },
props: { props: {
from: String from: String
@@ -218,7 +243,8 @@ export default {
dialogShowText: false, dialogShowText: false,
dialogText: '', dialogText: '',
isError: false, isError: false,
errorContent: '' errorContent: '',
chartInfo: {}
} }
}, },
methods: { methods: {
@@ -493,7 +519,6 @@ export default {
} }
this.$get('/alert/rule/' + row.alertRule.id).then(res => { this.$get('/alert/rule/' + row.alertRule.id).then(res => {
this.currentMsg = { ...row, alertRule: { ...res.data } } this.currentMsg = { ...row, alertRule: { ...res.data } }
this.graphShow = true
this.$nextTick(() => { this.$nextTick(() => {
this.searchTime = [bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000), bus.computeTimezoneTime(new Date().getTime())] this.searchTime = [bus.computeTimezoneTime(new Date().getTime() - 1 * 60 * 60 * 1000), bus.computeTimezoneTime(new Date().getTime())]
this.queryDate() this.queryDate()
@@ -683,12 +708,15 @@ export default {
queryDate () { queryDate () {
this.chartLoading = true this.chartLoading = true
if (this.currentMsg.alertRule.type === 1) { if (this.currentMsg.alertRule.type === 1) {
this.resultType = 'matrix' const chartInfo = lodash.cloneDeep(lineData)
this.$nextTick(() => { chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, ''))
this.queryChartDate() chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
}) this.showFullscreen(true, chartInfo)
} else if (this.currentMsg.alertRule.type === 2) { } else if (this.currentMsg.alertRule.type === 2) {
this.queryLogData(1000) const chartInfo = lodash.cloneDeep(logData)
chartInfo.elements[0].expression = encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, ''))
chartInfo.elements[0].filter = encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))
this.showFullscreen(true, chartInfo)
} }
}, },
exportLog ({ limit, descending }) { exportLog ({ limit, descending }) {
@@ -841,6 +869,10 @@ export default {
showText (row) { showText (row) {
this.dialogShowText = true this.dialogShowText = true
this.dialogText = row.alertRule.trbShot this.dialogText = row.alertRule.trbShot
},
showFullscreen (show, chartInfo) {
this.chartInfo = chartInfo
this.graphShow = show
} }
} }
} }

View File

@@ -120,37 +120,6 @@
@showFullscreen="showFullscreen" @showFullscreen="showFullscreen"
></panel-chart> ></panel-chart>
</el-dialog> </el-dialog>
<!-- <el-dialog id="viewGraphDialog"-->
<!-- :modal-append-to-body='false'-->
<!-- destroy-on-close-->
<!-- :title="$t('overall.detail')"-->
<!-- :visible.sync="graphShow"-->
<!-- class="line-chart-block-modal nz-dialog endpoint-dialog"-->
<!-- width="90%"-->
<!-- @close="dialogClose">-->
<!-- <el-popover-->
<!-- v-if="isError"-->
<!-- placement="top-start"-->
<!-- :close-delay=10-->
<!-- trigger="hover"-->
<!-- popper-class="chart-error-popper">-->
<!-- <div >{{errorContent}}</div>-->
<!-- <span slot="reference" class="panel-info-corner panel-info-corner&#45;&#45;error">-->
<!-- <i class="nz-icon nz-icon-warning fa-model" ></i>-->
<!-- <span class="panel-info-corner-inner"></span>-->
<!-- </span>-->
<!-- </el-popover>-->
<!-- <div slot="title">-->
<!-- {{$t("project.endpoint.dialogTitle")}}-->
<!-- <div class="float-right panel-calendar dialog-tool" style="display: flex">-->
<!-- <pick-time v-model="searchTimeDialog" :refresh-data-func="queryDate" :use-chart-unit="false" :use-refresh="false" style="height: 28px;"></pick-time>-->
<!-- </div>-->
<!-- </div>-->
<!-- <div style="width: 100%;height: 100%" v-loading="chartLoading">-->
<!-- <chart v-if="resultType === 'matrix'" ref="messageChart" :unit="chartUnit" name="alertMessageChart"></chart>-->
<!-- <log-tab v-if="resultType === 'streamsFormat'" ref="logDetailScreen" :log-data="logData" :showSwitch="false" :tab-index="tabIndex" @exportLog="exportLog" @limitChange="queryLogData"></log-tab>-->
<!-- </div>-->
<!-- </el-dialog>-->
<!--全屏--> <!--全屏-->
<el-dialog class="nz-dialog table-chart-dialog" :title="$t('alert.config.trbShot')" <el-dialog class="nz-dialog table-chart-dialog" :title="$t('alert.config.trbShot')"
:visible.sync="dialogShowText" :visible.sync="dialogShowText"
@@ -614,126 +583,6 @@ export default {
this.showFullscreen(true, chartInfo) this.showFullscreen(true, chartInfo)
} }
}, },
queryChartDate () {
const $temp = this
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.searchTimeDialog = [start, end]
const timeDiff = (new Date(end).getTime() - new Date(start).getTime()) / 1000 / (24 * 60 * 60)
let step = '15s'
if (timeDiff < 1) {
step = '15s'
} else if (timeDiff < 7) {
step = '5m'
} else if (timeDiff < 30) {
step = '10m'
} else {
step = '30m'
}
if (this.$refs.messageChart) {
this.$refs.messageChart.startLoading()
const axiosArr = []
axiosArr.push(axios.get('/prom/api/v1/query_range?query=' + encodeURIComponent(this.currentMsg.alertRule.expr.replace(/\"/g, '\'').replace(/\r|\n+/g, '')) + '&start=' + this.$stringTimeParseToUnix(start) + '&end=' + this.$stringTimeParseToUnix(end) + '&step=' + step + '&filter=' + encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))))
this.legend = []
this.chartDatas = []
axios.all(axiosArr).then(res => {
this.chartLoading = false
try {
res.forEach((response, promIndex) => {
if (response.status === 200) {
if (response.data.status === 'success') {
const queryData = response.data.data.result[0]
if (queryData) {
const chartData = {
type: 'line',
symbol: 'none', // 去掉点
smooth: 0.2, // 曲线变平滑
name: '',
lineStyle: {
width: 1,
opacity: 0.9
},
markLine: {
silent: true,
symbol: ['circle', 'circle'],
label: {
distance: this.computeDistance(chartDataFormat.getUnit(this.currentMsg.alertRule.unit ? this.currentMsg.alertRule.unit : 2).compute(this.currentMsg.alertRule.threshold)),
formatter (params) {
return chartDataFormat.getUnit($temp.currentMsg.alertRule.unit ? $temp.currentMsg.alertRule.unit : 2).compute(params.value)
}
},
lineStyle: {
color: '#d64f40',
width: 2,
type: 'dotted'
},
data: [{
yAxis: Number(this.currentMsg.alertRule.threshold)
}]
},
markArea: {
itemStyle: {
color: '#d64f40',
opacity: 0.1
},
data: [this.returnMarkArea()]
}
}
if (this.currentMsg.alertRule.operator == '==' || this.currentMsg.alertRule.operator == '!=') {
delete chartData.markArea
}
let alias = chartData.name
chartData.name += '{'
alias += '{'
Object.keys(queryData.metric).forEach((item, index) => {
const label = item
const value = queryData.metric[label]
chartData.name += label + "='" + value + "',"
})
chartData.name = chartData.name.charAt(chartData.name.length - 1) == ',' ? chartData.name.substr(0, chartData.name.length - 1) : chartData.name
chartData.name += '}'
const legend = {
name: chartData.name,
alias: chartData.name,
isGray: false
}
this.legend.push(legend)
chartData.data = queryData.values.map((dpsItem, dpsIndex) => {
return [dpsItem[0] * 1000, parseFloat(dpsItem[1]).toFixed(2)]
})
this.chartDatas.push(chartData)
}
} else {
this.$message.error(response.data.error)
}
} else {
this.$refs.messageChart.endLoading()
this.chartLoading = false
this.isError = true
if (response.msg) {
this.errorContent = response.msg
} else if (response.error) {
this.errorContent = response.error
} else {
this.errorContent = response
}
}
})
this.$nextTick(() => {
this.$refs.messageChart.setRandomColors(this.chartDatas.length)
this.$refs.messageChart.setLegend(this.legend)
this.$refs.messageChart.setSeries(this.chartDatas)
this.$refs.messageChart.endLoading()
this.$refs.messageChart.resize()
})
} catch (err) {
// this.$message.error(err)
this.$refs.messageChart.endLoading()
this.chartLoading = false
}
})
}
},
exportLog ({ limit, descending }) { exportLog ({ limit, descending }) {
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)
const end = this.searchTimeDialog[1] ? this.searchTimeDialog[1] : bus.computeTimezoneTime(new Date().getTime()) const end = this.searchTimeDialog[1] ? this.searchTimeDialog[1] : bus.computeTimezoneTime(new Date().getTime())
@@ -774,33 +623,6 @@ export default {
reader.readAsText(error.response.data) reader.readAsText(error.response.data)
}) })
}, },
queryLogData (limit) { // log的chart和table是一个请求
if (!limit) {
limit = 100
}
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=' + encodeURIComponent(this.currentMsg.alertRule.expr) + '&start=' + this.$stringTimeParseToUnix(start) + '&end=' + this.$stringTimeParseToUnix(end) + '&limit=' + limit + '&filter=' + encodeURIComponent(decodeURIComponent(this.promQueryParamLabels(this.currentMsg.labels)))).then(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 () { loadLogGraph () {
const graphData = this.logData.filter(l => l.resultType === 'matrix') const graphData = this.logData.filter(l => l.resultType === 'matrix')
if (graphData && graphData.length > 0) { if (graphData && graphData.length > 0) {