1. 前言
运维系统接入日志查询,开发日志上下文功能方便查看日志。 参照阿里云日志服务控制台上下文浏览。
图1-1.日志上下文浏览图
2. 效果
查看日志列表时,选中某条日志查看其上下文,查询指定日志前后紧邻时间的记录。效果是抽屉加滚动列表;element-ui 组件支持InfiniteScroll(无限滚动组件)和Drawer(抽屉组件)实现。此处使用原生HTML 标签及CSS 样式自定义实现Drawer 效果。
图2-1.日志查询列表图
选中某行日志记录,展开日志可选择查询上下文,上下文查询支持查询紧邻的更早时间记录,更新可查看当前日志时间点之后紧邻的记录。
图2-2.日志查询上下文图
图2-3.日志查询上下文更早日志图
图2-4.日志查询上下文更新日志图
3. 实现
日志查询模块文件结构如图
图3-1.日志查询文件结构图
NSTableAnalysisLog.js 和NSTableAnalysisLog.vue 是图2-1.日志查询日志列表图中的日志表单列表效果页。日志上下文效果在index.vue 文件实现。 此处贴出index.vue 和index.js 文件代码。
3.1 index.vue
<template>
<div class="page-operate-analysis-log">
<ns-table-analysis-log/>
<div class="ns-drawer">
<div :class="drawer?'mask':''"/>
<div :class="drawer?'open':'close'">
<ns-button @click="closeDrawer()" class="ns-drawer-close" icon="el-icon-close" circle></ns-button>
<div class="ns-drawer-header">
日志上下文浏览
</div>
<br/>
<ns-button class="ns-button" type="info" @click="handleTopMore">更早
</ns-button>
<div class="ns-loading">
<span v-if="topLoading">加载中...
</span>
</div>
<div class="ns-data-log" v-for="(dataLog, index) in dataLogList" :key="index">
<pre>
<font v-if="dataLog.orderNumber > 0" color=red>【{{dataLog.orderNumber}}】
</font><font v-if="dataLog.orderNumber < 0" color=blue>【{{dataLog.orderNumber}}】
</font><font v-if="dataLog.orderNumber === 0" color=black>【{{dataLog.orderNumber}}】
</font><b>【{{dataLog.time}}】{{dataLog.level}}:{{dataLog.location}}
</b>
<b>日志信息
</b>:{{dataLog.message}}
<b>日志详情
</b>:{{dataLog.log}}
</pre>
</div>
<div class="ns-loading">
<span v-if="buttomLoading">加载中...
</span>
<span v-if="!topLoading && !buttomLoading && dataLogList.length === 0">暂无数据
</span>
</div>
<ns-button class="ns-button" type="info" @click="handleButtomMore">更新
</ns-button>
</div>
</div>
</div>
</template>
<script>
import NsTableAnalysisLog from './NsTableAnalysisLog'
import index from './src'
index.components = {
NsTableAnalysisLog
}
export default index
</script>
<style>
pre {
display: block;
font-family: -moz-fixed;
margin: 1em 0;
white-space: pre-wrap;
word-wrap: break-word;
}
.ns-button {
width: 100%;
}
.ns-data-log {
background: #FAFAFA;
margin: 5px;
}
.ns-loading {
text-align: center;
font-weight: 700;
margin: 10px;;
}
.ns-drawer {
.mask {
position: fixed;
z-index: 10;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .1);
}
.close {
position: absolute;
z-index: 10;
left: -800px;
top: 0;
width: 800px;
height: 100%;
background: #fff;
transition: left linear 1s;
}
.open {
z-index: 10;
right: 0;
top: 0;
width: 70%;
height: 100%;
padding-left: 1%;
padding-right: 1%;
float: right;
overflow-y: auto;
position: fixed;
background: #fff;
transition: left linear 1s;
.ns-drawer-header {
margin-top: 10%;
font-size: 14px;
font-weight: 700;
float: right;
}
.ns-drawer-close {
margin-top: 5%;
position: fixed;
}
}
}
</style>
3.2 index.js
import NsTableAnalysisLog
from '../NsTableAnalysisLog'
export default {
name
: 'OperateAnalysisLog',
components
: {
NsTableAnalysisLog
},
data () {
return {
platformSLSType
: '',
startTime
: '',
endTime
: '',
dataLogList
: [],
topLoading
: false,
topNoMore
: false,
buttomLoading
: false,
buttomNoMore
: false,
drawer
: false
}
},
methods
: {
showDrawer (row
, platformSLSType
, date
) {
this.buttomLoading
= true
this.platformSLSType
= platformSLSType
this.startTime
= date
[0]
this.endTime
= date
[1]
this.drawer
= true
let type
= 0
this.handleCursorLogContext(row
, type
)
},
closeDrawer () {
this.buttomLoading
= false
this.topLoading
= false
this.drawer
= false
this.dataLogList
= []
},
handleButtomMore () {
this.buttomLoading
= true
let type
= 0
let size
= this.dataLogList
.length
- 1
let row
= this.dataLogList
[size
]
this.handleCursorLogContext(row
, type
)
},
handleTopMore () {
this.topLoading
= true
let type
= 1
let row
= this.dataLogList
[0]
this.handleCursorLogContext(row
, type
)
},
handleCursorLogContext (row
, type
) {
if (row
=== undefined
|| row
=== null) {
this.$notify
.warning('当前日志上下文暂无数据!')
this.buttomLoading
= false
this.topLoading
= false
return
}
if (this.dataLogList
.length
> 300) {
this.$notify
.warning('当前日志上下文已超出300条记录!')
this.buttomLoading
= false
this.topLoading
= false
return
}
let params
= {
startTime
: this.startTime
,
endTime
: this.endTime
,
fromTime
: row
.time
,
logStore
: this.platformSLSType
,
type
: type
}
this.$http
.fetch(this.$api
.operate
.analysisLog
.findCursorLogList
, params
)
.then((resp
) => {
let resultLength
= resp
.result
.length
let dataLogListLength
= this.dataLogList
.length
if (type
=== 0) {
let resultData
= []
for (var index
= 0; index
< resultLength
; index
++) {
let resultIndex
= resp
.result
[index
]
let indexOfFlag
= false
for (let dataLog
of this.dataLogList
) {
if (dataLog
.level
=== resultIndex
.level
&& dataLog
.location
=== resultIndex
.location
&& dataLog
.log
=== resultIndex
.log
&& dataLog
.message
=== resultIndex
.message
&& dataLog
.time
=== resultIndex
.time
) {
indexOfFlag
= true
}
}
if (indexOfFlag
) {
continue
}
if (index
=== 0 && this.dataLogList
.length
=== 0) {
resultIndex
.orderNumber
= 0
} else if (index
=== 0 && this.dataLogList
.length
> 0) {
resultIndex
.orderNumber
= this.dataLogList
[this.dataLogList
.length
- 1].orderNumber
+ 1
} else if (index
> 0) {
resultIndex
.orderNumber
= resp
.result
[index
- 1].orderNumber
+ 1
}
resultData
.push(resultIndex
)
}
this.dataLogList
= this.dataLogList
.concat(resultData
)
} else if (type
=== 1) {
for (var i
= resultLength
- 1; i
> 0; i
--) {
if (this.dataLogList
.indexOf(resp
.result
[i
]) !== -1) {
continue
}
let tempData
= []
if (i
=== resultLength
- 1 && this.dataLogList
.length
=== 0) {
resp
.result
[i
].orderNumber
= 0
} else if (i
=== resultLength
- 1 && this.dataLogList
.length
> 0) {
resp
.result
[i
].orderNumber
= this.dataLogList
[0].orderNumber
- 1
tempData
.push(resp
.result
[i
])
this.dataLogList
= tempData
.concat(this.dataLogList
)
} else if (i
> 0) {
resp
.result
[i
].orderNumber
= resp
.result
[i
+ 1].orderNumber
- 1
tempData
.push(resp
.result
[i
])
this.dataLogList
= tempData
.concat(this.dataLogList
)
}
}
}
if (dataLogListLength
=== this.dataLogList
.length
) {
this.$notify
.warning('暂无更多数据!')
}
}).catch((resp
) => {
this.$notify
.warning(resp
.msg
)
}).finally(() => {
this.buttomLoading
= false
this.topLoading
= false
})
}
}
}
3.3 附件:日志记录实体类SLSMessageVo.java
import io
.swagger
.annotations
.ApiModelProperty
;
import lombok
.Getter
;
import lombok
.Setter
;
import lombok
.ToString
;
@Setter
@Getter
@ToString
public class SLSMessageVo {
@ApiModelProperty(value
= "日志级别")
private String level
;
@ApiModelProperty(value
= "location")
private String location
;
@ApiModelProperty(value
= "日志信息")
private String message
;
@ApiModelProperty(value
= "日志时间")
private String time
;
@ApiModelProperty(value
= "日志详情")
private String log
;
@ApiModelProperty(value
= "序号")
private Integer orderNumber
;
}
The End