123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902 |
- <template>
- <BasicLayout>
- <template #wrapper>
- <el-card class="box-card" style="flex:1;">
- <div >
- <el-page-header @back="back">
- <div slot="content">
- <span style="font-size:18px;margin-right:16px;">{{ detailTitle }}</span>
- <el-button
- size="small"
- type="primary"
- @click.native.stop="handleUpdateName()"
- >修改业务别名</el-button>
- </div>
- </el-page-header>
- </div>
- <div >
- <div class="flexWrap">
- <div class="flex-left">
- <div class="ob-switch-box">
- <el-switch
- v-model="switchValue"
- active-color="#165DFF"
- inactive-color="#C9CDD4"
- @change="handelSwitch"
- />
- </div>
- <div v-if="switchValue">
- <div v-if="JSON.stringify(graphData)!="{}"" v-loading="loading">
- <div style="font-size:14px;font-weight:bold;text-align:right">
- <svg-icon :icon-class="isFull?'exit-fullscreen':'fullscreen'" @click.native.prevent="clickFull" />
- </div>
- <Topo ref="topo" :graph-data="graphData" topo-id="container" @changeState="clickRowHandleNode" />
- </div>
- </div>
- <div v-else style="position:relative;height: 100%;">
- <div v-if="isLoading" v-loading="isLoading" class="loading-overlay"></div>
- <div v-else>
- <NodeG6Charts v-if="sweetGraphData && Object.keys(sweetGraphData).length > 0" :chart-content-id="'serviceDrawerContainer'" :graph-data="sweetGraphData" />
- </div>
- </div>
- </div>
- <div class="flex-right">
- <div id="scaleMain" style="width:100%;height:240px;margin-bottom:36px;margin-top:16px" />
- <div style="text-align: right; padding-right:10px;">
- <el-checkbox v-model="checked" style="margin-bottom:10px" @change="handelCheckChange(checked)">Duration > 2500ms</el-checkbox>
- <el-checkbox v-model="onlyException" style="margin-bottom:10px" @change="handelChange()">仅异常</el-checkbox>
- </div>
- <el-table
- v-loading="tableLoading"
- :data="rowData"
- @sort-change="sortChangeTable"
- >
- <el-table-column header-align="center" label="TraceID" prop="trace_id" align="center" width="240">
- <template slot-scope="scope">
- <span @click="goto(scope.row)">{{ scope.row.trace_id }}</span>
- </template>
- </el-table-column>
- <el-table-column header-align="center" label="SpanName" prop="span_name" align="center" :show-overflow-tooltip="true" />
- <el-table-column header-align="center" label="DateTime" sortable="custom" prop="datetime" align="center" :show-overflow-tooltip="true" />
- <el-table-column header-align="center" label="Duration(ms)" sortable="custom" prop="duration" width="140" align="center">
- <template slot-scope="scope">
- <el-tag v-if="scope.row.duration>=2000" type="danger">{{ scope.row.duration }}</el-tag>
- <el-tag v-if="scope.row.duration<2000" type="info">{{ scope.row.duration }}</el-tag>
- </template>
- </el-table-column>
- </el-table>
- <pagination
- v-show="total>0"
- :total="total"
- :page.sync="childQueryParams.pageIndex"
- :limit.sync="childQueryParams.pageSize"
- @pagination="handelgetBizDetail"
- />
- </div>
- </div>
- <!-- 添加或修改应用配置对话框 -->
- <el-dialog v-if="open" :title="title" :visible.sync="open" width="700px" :center="true" :close-on-click-modal="false">
- <el-form ref="form" :model="form" label-width="95px">
- <el-form-item label="中文别名" prop="name">
- <el-input v-model="form.name" placeholder="请输入中文别名" />
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="submitForm">确 定</el-button>
- <el-button @click="cancel">取 消</el-button>
- </div>
- </el-dialog>
- <el-dialog
- :visible.sync="Visible"
- :fullscreen="true"
- center
- :show-close="false"
- >
- <Topo :graph-data="graphData" topo-id="container1" @changeState="clickRowHandleNode" />
- </el-dialog>
- </div>
- <el-drawer
- :visible.sync="drawer"
- direction="rtl"
- size="50%"
- @close="drawerClose"
- >
- <h4 slot="title" style="font-size:16px">{{ detailData.name }}</h4>
- <div class="node-details">
- <div class="node-details-content">
- <div class="node-details-content-section">
- <div style="display:flex;justify-content: space-between;">
- <div class="node-details-content-section-header"><a href="" _blank>节点信息</a></div>
- <div>
- <el-button size="mini" type="primary" plain @click="editNodeName()">修改节点别名</el-button>
- </div>
- </div>
- <div>
- <div class="node-details-info-field" style="position:relative;display:flex;">
- <div class="node-details-info-field-label truncate w50" style="width:50%">节点名称:</div>
- <div class="node-details-info-field-value truncate" style="width:50%">
- {{ detailData.name }}
- </div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">所属服务:</div>
- <!-- 目前后端没返回服务别名,中文名的字段 -->
- <div class="node-details-info-field-value truncate w50" style="width:50%;color:#1890ff;cursor: pointer;" @click="gotoPathService("/service/serviceDetail/index",detailData.service_name)">
- {{ detailData.service_name }}
- </div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">Span名称:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ detailData.span_name }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">Span类型:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ detailData.span_kind }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">成功率:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ ((detailData.rate || 0)*100).toFixed(2)+'%' }}</div>
- </div>
- </div>
- </div>
- <div v-if="detailData.span_type == "http server"" class="node-details-content-section">
- <div class="node-details-content-section-header">接口信息</div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">请求量:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ nodeStats.total }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">错误率:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ ((nodeStats.error_rate || 0) *100 ).toFixed(4) + '%' }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">P50:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ (nodeStats.p50 || 0 ).toFixed(2) +'ms' }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">P90:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ (nodeStats.p90 || 0).toFixed(2) +'ms' }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">P99:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ (nodeStats.p99 || 0).toFixed(2) +'ms' }}</div>
- </div>
- <div>
- <div class="node-details-info-field" style="cursor: pointer;" @click="gotoPath("/service/InterfaceDetail/index",nodeStats)">
- <div class="node-details-info-field-label truncate w50" style="width:50%">接口名:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%;color:#1890ff;cursor: pointer;">{{ nodeStats.name }}</div>
- </div>
- <div class="node-details-info-field">
- <div class="node-details-info-field-label truncate w50" style="width:50%">接口地址:</div>
- <div class="node-details-info-field-value truncate w50" style="width:50%">{{ nodeStats.value }}</div>
- </div>
- </div>
- </div>
- <div class="node-details-content-section">
- <div class="node-details-content-section-header">Span列表</div>
- <div>
- <el-table
- v-loading="nodeloading"
- :data="nodeSpansList"
- @row-click="handleRowClick"
- >
- <el-table-column label="链路标识" prop="trace_id" :show-overflow-tooltip="true" />
- <el-table-column label="Method" prop="method" :show-overflow-tooltip="true" />
- <el-table-column label="Code" prop="code" :show-overflow-tooltip="true" />
- <el-table-column label="Duration(ms)" sortable="custom" prop="duration" :show-overflow-tooltip="true" />
- </el-table>
- <pagination
- v-show="nodeCount>0"
- small
- :total="nodeCount"
- :page.sync="querySpans.pageIndex"
- :limit.sync="querySpans.pageSize"
- @pagination="getNodeSpans"
- />
- </div>
- </div>
- </div>
- </div>
- </el-drawer>
- <el-dialog v-if="nodeOpen" title="修改节点别名" :visible.sync="nodeOpen" width="700px" :center="true" :close-on-click-modal="false">
- <el-form ref="queryName" :model="queryName" label-width="95px">
- <el-form-item label="节点别名" prop="name">
- <el-input v-model="queryName.name" placeholder="请输入节点别名" />
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button type="primary" @click="saveNodeName">确 定</el-button>
- <el-button @click="cancelNode">取 消</el-button>
- </div>
- </el-dialog>
- </el-card>
- </template>
- </BasicLayout>
- </template>
- <script>
- import storage from '@/utils/storage'
- import { getBizDetail, listBizGraph, updateBiz, listBiz, bizNodeStats, bizNodeName, bizNodeSpans, getSweetList, addUrlMapping, listBizStats } from '@/api/mapping'
- import Topo from './components/Topo'
- import resize from '../mixins/resize'
- import moment from 'moment'
- import NodeG6Charts from '../../service/InterfaceDetail/components/NodeG6Charts.vue'
- export default {
- components: {
- Topo,
- NodeG6Charts
- },
- mixins: [resize],
- data() {
- return {
- nodeOpen: false,
- drawer: false,
- isFull: false,
- Visible: false,
- loading: false,
- open: false,
- form: {},
- // 表单校验
- rules: {
- name: [
- { required: true, message: '接口名称不能为空', trigger: 'blur' }
- ]
- },
- title: '修改业务别名',
- // 查询参数
- queryParams: {
- // start_time:Math.round((new Date().getTime())/1000 - (5*60)),
- // end_time:Math.round(new Date().getTime()/1000),
- app_id: '',
- start_time: '',
- end_time: '',
- pageIndex: 1,
- pageSize: 10
- },
- detailTitle: '',
- tableLoading: false,
- rowData: [],
- total: 0,
- childQueryParams: {
- // start_time:Math.round((new Date().getTime())/1000 - (5*60)),
- // end_time:Math.round(new Date().getTime()/1000),
- start_time: 0,
- end_time: 0,
- biz_id: 1,
- pageIndex: 1,
- pageSize: 10,
- sort_type: 'DESC',
- sort_field: 'Timestamp',
- min_duration: 0,
- only_exception: false
- },
- BizStatsQuery: {
- biz_id: 0,
- start_time: '',
- end_time: ''
- },
- graphData: {},
- detailObj: {},
- timer: null,
- detailData: {},
- queryStats: {
- id: 0,
- // hash:'',//和id二选一
- start_time: 0,
- end_time: 0
- },
- nodeStats: {},
- queryName: {
- id: 0,
- // hash:'',//和id二选一
- name: ''
- },
- querySpans: {
- id: 0,
- // hash:'',//和id二选一
- start_time: '',
- end_time: '',
- pageIndex: 1,
- pageSize: 10
- },
- nodeSpansList: [],
- nodeCount: 0,
- nodeloading: false,
- checked: false,
- onlyException: false,
- switchValue: false,
- isLoading: false,
- sweetquanParams: {
- biz_id: 0,
- start_time: '',
- end_time: ''
- },
- sweetGraphData:{},
- appItem: {},
- chartQuantiles: {
- biz_id: null,
- start_time: '',
- end_time: ''
- }
- }
- },
- watch: {
- '$store.state.time.globalTimes': {
- handler(newValue, oldValue) {
- if (newValue) {
- this.childQueryParams.start_time = newValue.startTime
- this.childQueryParams.end_time = newValue.endTime
- this.queryParams.start_time = newValue.startTime
- this.queryParams.end_time = newValue.endTime
- this.queryParams.pageIndex = 1
- this.querySpans.start_time = newValue.startTime
- this.querySpans.end_time = newValue.endTime
- this.queryStats.start_time = newValue.startTime
- this.queryStats.end_time = newValue.endTime
- this.sweetquanParams.start_time = newValue.startTime
- this.sweetquanParams.end_time = newValue.endTime
- this.chartQuantiles.start_time = newValue.startTime
- this.chartQuantiles.end_time = newValue.endTime
- this.querySpans.pageIndex = 1
- this.getList() // 获取前一个页面-解析列表的table 数据
- this.handelgetBizDetail()// 获取table 表格
- //
- if (this.switchValue) {
- this.getListBizGraph(this.$route.query.id)// 获取紧凑树接口
- } else {
- this.getSweetListFn() // 获取甜甜圈接口
- }
- if (newValue.timeOut) {
- if (newValue.timeOut == 1) {
- clearInterval(this.timer)
- } else {
- clearInterval(this.timer)
- this.Refresh(newValue.timeOut)
- }
- }
- }
- },
- // immediate: true,
- deep: true
- }
- },
- created() {
- const start_time = this.$store.state.time.globalTimes.startTime
- const end_time = this.$store.state.time.globalTimes.endTime
- this.childQueryParams.start_time = start_time
- this.childQueryParams.end_time = end_time
- this.queryParams.start_time = start_time
- this.queryParams.end_time = end_time
- this.querySpans.start_time = start_time
- this.querySpans.end_time = end_time
- this.queryStats.start_time = start_time
- this.queryStats.end_time = end_time
- this.sweetquanParams.start_time = start_time
- this.sweetquanParams.end_time = end_time
- this.chartQuantiles.start_time = start_time
- this.chartQuantiles.end_time = end_time
- this.appItem = storage.get('appsItem')
- this.detailObj = storage.get('detailObj')
- if (this.$route.query.id != undefined) {
- this.childQueryParams.biz_id = this.$route.query.id
- this.chartQuantiles.biz_id = this.$route.query.id
- this.detailTitle = this.$route.query.name
- this.queryParams.app_id = this.appItem.id
- this.sweetquanParams.biz_id = this.$route.query.id
- this.handelgetBizDetail()
- this.getList()
- if (this.switchValue) {
- this.getListBizGraph(this.$route.query.id)
- } else {
- this.getSweetListFn()
- }
- }
- },
- mounted() {
- // this.$nextTick(() => {
- // if (document.getElementById('scaleMain')){
- // this.drawEchartsScale(this.detailObj)
- // }
- // })
- },
- beforeDestroy() {
- clearInterval(this.timer)
- this.graphData = {}
- },
- methods: {
- handelSwitch() {
- if (this.switchValue) {
- this.getListBizGraph(this.sweetquanParams.biz_id)
- } else {
- this.getSweetListFn()
- }
- },
- async getSweetListFn() {
- this.isLoading = true
- this.sweetGraphData = {}
- const res = await getSweetList(this.sweetquanParams)
- if (res && res.code === 200) {
- this.sweetGraphData = res.data
- } else {
- this.sweetGraphData = {}
- }
- this.isLoading = false
- },
- gotoPathService(path, service_name) {
- const href = this.$router.resolve({
- path: path,
- query: {
- service_name: service_name
- }
- })
- window.open(window.location.origin + '/' + href.href, '_blank')
- },
- gotoPath(path, row) {
- storage.set('row', row)
- const href = this.$router.resolve({
- path: path,
- query: {
- name: row.name,
- kind: row.value,
- method: row.http_method,
- service_name: row.service_name
- }
- })
- window.open(window.location.origin + '/' + href.href, '_blank')
- },
- handleRowClick(row, column, event) {
- const datetime = Date.parse(row.datetime) / 1000
- const href = this.$router.resolve({
- path: '/latency/index',
- query: {
- id: row.trace_id,
- span_id: row.span_id,
- datetime: datetime
- }
- })
- window.open(window.location.origin + '/' + href.href, '_blank')
- },
- clickRowHandleNode(item) {
- this.detailData = {}
- this.detailData = item
- this.queryStats.id = Number(item.unique_id)
- this.queryName.id = Number(item.unique_id)
- this.queryName.name = item.name
- this.querySpans.id = Number(item.unique_id)
- if (item.span_type == 'http server') {
- this.getNodeStats()
- }
- this.getNodeSpans()
- this.drawer = true
- },
- getNodeStats() {
- bizNodeStats(this.queryStats).then(res => {
- if (res&& res.code == 200) {
- this.nodeStats = res.data
- }
- })
- },
- saveNodeName() {
- bizNodeName(this.queryName).then(res => {
- if (res.code == 200) {
- this.msgSuccess(res.msg)
- this.nodeOpen = false
- this.drawer = false
- this.graphData = {}
- // window.location.reload();
- this.handelgetBizDetail()
- this.getListBizGraph(this.$route.query.id)
- }
- })
- },
- cancelNode() {
- this.nodeOpen = false
- },
- getNodeSpans() {
- this.nodeloading = true
- bizNodeSpans(this.querySpans).then(res => {
- if (res.code == 200) {
- this.nodeloading = false
- this.nodeSpansList = res.data.list
- this.nodeCount = res.data.count
- }
- })
- },
- editNodeName() {
- this.nodeOpen = true
- },
- drawerClose() {
- this.drawer = false
- },
- clickFull() {
- this.Visible = true
- // this.$refs['topo'].initGraph();
- },
- handleUpdateName() {
- this.open = true
- this.form = this.detailObj
- delete this.form.quantiles
- },
- /** 提交按钮 */
- submitForm: function() {
- this.$refs['form'].validate(valid => {
- if (valid) {
- if (this.form.id !== undefined || this.form.id != 0) {
- updateBiz(this.form, this.form.id).then(response => {
- if (response.code === 200) {
- this.msgSuccess(response.msg)
- this.open = false
- this.drawer = false
- this.$router.push({
- path: '/business-analysis/analysis/index'
- })
- } else {
- this.msgError(response.msg)
- }
- })
- } else {
- addUrlMapping(this.form).then(response => {
- if (response.code === 200) {
- this.msgSuccess(response.msg)
- this.open = false
- this.queryParams.pageIndex = 1
- this.serveceMapList = []
- this.tempList = []
- this.getList()
- } else {
- this.msgError(response.msg)
- }
- })
- }
- }
- })
- },
- // 取消按钮
- cancel() {
- this.open = false
- this.reset()
- },
- getList() { // 获取前一个页面-解析列表的table 数据
- listBiz(this.queryParams).then(res => {
- if (res.code == 200) {
- for (let i = 0; i < res.data.list.length; i++) {
- if (res.data.list[i].id == this.$route.query.id) {
- this.detailTitle = res.data.list[i].name
- this.detailObj = res.data.list[i]
- listBizStats(this.chartQuantiles).then(response => {
- if (response.code == 200) {
- if (response.data.biz_id != undefined) {
- if (this.detailObj.id == response.data.biz_id) {
- this.detailObj = Object.assign({}, this.detailObj, response.data)
- storage.set('detailObj', this.detailObj)
- setTimeout(()=>{
- this.drawEchartsScale(this.detailObj)
- },100)
- }
- }
- }
- })
- }
- }
- }
- })
- },
- // 表单重置
- reset() {
- this.form = {
- id: undefined,
- name: undefined,
- url: undefined,
- type: undefined,
- module: undefined,
- summary: undefined,
- favor: undefined
- }
- this.resetForm('form')
- },
- Refresh(timeOut) {
- this.timer = setInterval(() => {
- this.handelgetBizDetail()
- this.getListBizGraph(this.$route.query.id)
- }, timeOut)
- },
- back() {
- this.$router.push({
- path: '/business-analysis/analysis/index'
- })
- },
- handelgetBizDetail() {// 获取table 表格
- this.tableLoading = true
- getBizDetail(this.childQueryParams).then(res => {
- if (res.code == 200) {
- this.tableLoading = false
- this.rowData = res.data.list
- this.total = res.data.count
- }
- })
- },
- getListBizGraph(id) {
- this.loading = true
- listBizGraph({ biz_id: id }).then((res) => {
- this.graphData = {}
- if (res.code == 200) {
- const arr = res.data
- if (arr.length > 0) {
- const List = this.handelListBizData(arr)
- this.graphData = List[0]
- this.loading = false
- } else {
- this.graphData = {}
- }
- }
- })
- },
- handelListBizData(data) {
- data.forEach((v, k) => {
- // v.collapsed = false;
- v.id = v.id.toString()
- v.name = v.name
- v.label = v.stats.duration != undefined ? (v.stats.duration).toString() : ''
- v.currency = 'ms'
- v.rate = v.stats.success_rate
- v.status = v.stats.success_rate >= 0.6 ? 'B' : v.stats.success_rate == 0 ? 'DI' : 'R'
- v.variableValue = v.stats.success_rate
- v.variableUp = v.stats.success_rate_up
- if (v.children != undefined && v.children.length > 0) {
- v.children = this.handelListBizData(v.children)
- }
- })
- return data
- },
- drawEchartsScale(row) {
- const _this = this
- let myChartScale = this.$echarts5.getInstanceByDom(document.getElementById('scaleMain'));
- if (myChartScale == undefined) {
- myChartScale = this.$echarts5.init(document.getElementById('scaleMain'));
- }
- // 绘制趋势echarts
- const option = {
- tooltip: {
- trigger: 'axis',
- confine: false,
- appendToBody: true,
- show: true,
- formatter: function(params) {
- storage.set('paramsValue', params)
- const axisValueLabel = params[0].axisValueLabel
- let str0 = ''
- params.forEach((item, idx) => {
- // str1+=`${}`
- str0 += `${item.marker}${item.seriesName}<span style='margin-left:30px;text-align:right;font-weight:400'>${item.data}</span>`
- switch (idx) {
- case 0:
- str0
- break
- case 1:
- str0
- break
- default:
- str0
- }
- str0 += idx === params.length - 1 ? '' : '<br/>'
- })
- return axisValueLabel + '<br>' + str0
- }
- },
- title: {
- text: '延迟比例',
- // subtext: 'ms',
- textStyle: {
- fontSize: 14
- }
- // triggerEvent: true,
- },
- grid: {
- // top:'5%',
- left: '3%',
- right: '6%',
- bottom: '1%',
- containLabel: true
- },
- xAxis: {
- type: 'category',
- boundaryGap: false,
- data: row.quantiles.time,
- axisLabel: {
- textStyle: {
- fontSize: 12,
- textAlign: 'center'
- },
- formatter: function(params) {
- // let newParams = moment(params).format('YYYY-MM-DD HH:mm:ss');
- // let newArr = newParams.split(' ')
- // let time = newArr[0] + "\n" + newArr[1]
- // return time;
- let newParams = ''
- const dateStr = params.substring(0, 10)
- // dateStr = dateStr.replace(/\-/g, function(match) {
- // return match.replace(/\-/g, '.');
- // });
- const timeStr = params.substring(11, 19)
- newParams = dateStr + '\n' + timeStr
- return newParams
- }
- }
- },
- yAxis: {
- type: 'value',
- scale: true,
- gridIndex: 0,
- axisLabel: {
- formatter: '{value}'
- },
- axisLine: {
- show: true
- },
- axisTick: {
- show: true
- },
- splitLine: {
- show: true
- }
- },
- series: [
- {
- name: 'P.50',
- type: 'line',
- stack: 'Total',
- symbol: 'none',
- // symbol: 'emptyCircle',//拐点
- data: row.quantiles.p50
- },
- {
- name: 'P.95',
- type: 'line',
- stack: 'Total',
- symbol: 'none', // 拐点
- // symbol: 'emptyCircle',//拐点
- data: row.quantiles.p90
- },
- {
- name: 'P.99',
- type: 'line',
- stack: 'Total',
- symbol: 'none', // 拐点
- // symbol: 'emptyCircle',//拐点
- data: row.quantiles.p99
- }
- ]
- }
- myChartScale.setOption(option)
- myChartScale.getZr().on('click', params => {
- const data = storage.get('paramsValue')
- const timestamp = moment(data[0].name).unix()
- _this.childQueryParams.start_time = timestamp
- _this.childQueryParams.end_time = timestamp
- _this.handelgetBizDetail()
- })
- },
- goto(row) {
- const datetime = Date.parse(row.datetime) / 1000
- const href = this.$router.resolve({
- path: '/latency/index',
- query: {
- id: row.trace_id,
- span_id: row.span_id,
- datetime: datetime
- }
- })
- window.open(window.location.origin + '/' + href.href, '_blank')
- },
- sortChangeTable(val) {
- const prop = val.prop
- this.childQueryParams.sort_field = prop === 'duration' ? 'Duration' : 'Timestamp'
- // desc(倒序)和asc(正序)
- if (val.order === 'descending') {
- this.childQueryParams.sort_type = 'DESC'
- } else if (val.order === 'ascending') {
- this.childQueryParams.sort_type = 'ASC'
- }
- this.handelgetBizDetail()
- },
- handelCheckChange() {
- this.childQueryParams.min_duration = this.checked ? 2500 : 0
- this.handelgetBizDetail()
- },
- handelChange() {
- this.childQueryParams.only_exception = this.onlyException ? 1 : 0
- this.handelgetBizDetail()
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .node-details{
- .node-details-content{
- // width:420px;
- padding:0 36px;
- overflow-y: scroll;
- font-family: proxima-nova, Helvetica, Arial, sans-serif;
- }
- .node-details-content-section{
- margin: 24px 0px;
- }
- .node-details-content-section-header{
- font-size: 14px;
- color:rgb(133,133,173);
- margin-bottom:20px;
- }
- .node-details-info-field{
- display: flex;
- -webkit-box-align: baseline;
- box-align:baseline;
- align-items: baseline;
- margin-bottom: 8px;
- }
- .node-details-info-field-label{
- text-align: right;
- // width: 30%;
- color: rgb(92, 92, 138);
- padding: 0px 0.5em 0px 0px;
- white-space: nowrap;
- font-size: 14px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space:nowrap;
- }
- .node-details-info-field-value{
- font-size: 14px;
- // flex: 0 0 0%;
- min-width: 0px;
- color: rgb(61, 61, 92);
- overflow: hidden;
- text-overflow: ellipsis;
- white-space:nowrap;
- }
- .truncate{
- overflow: hidden;
- text-overflow: ellipsis;
- white-space:nowrap;
- }
- .w50{
- width:50%;
- }
- }
- .ob-switch-box{
- text-align: right;
- width: 100%;
- margin-bottom: 10px;
- }
- ::v-deep .el-drawer__header {
- padding:16px;
- background:#1890ff;
- color:#fff;
- }
- ::v-deep .el-page-header__title{
- margin-top:3px;
- }
- </style>
|