1、整体涉及到修改的目录如下
2、graphql查询
2.1、修改GraphQLQueryProvider添加我们所需要的数据结构体,prepare方法里面添加
.file("query-protocol/log-from-es.graphqls")
.resolvers(new LogsFromEsQuery(getManager()))
2.2、log-from-es.graphqls
type EsData {
message: String
hostName: String
}
extend type Query {
esLogs(tid: String!,span: String!): [EsData]
}
2.3、LogsFromEsQuery
public class LogsFromEsQuery implements GraphQLQueryResolver {
private final ModuleManager moduleManager;
private LogsFromEsQueryService logsFromEsQueryService;
public LogsFromEsQuery(ModuleManager moduleManager){
this.moduleManager = moduleManager;
}
private LogsFromEsQueryService getLogsFromEsQueryService(){
if(null == logsFromEsQueryService){
this.logsFromEsQueryService = moduleManager.find(CoreModule.NAME).provider().getService(LogsFromEsQueryService.class);
}
return logsFromEsQueryService;
}
public List<EsData> esLogs(final String tid, final String span) throws IOException {
return getLogsFromEsQueryService().esLogs(tid,span);
}
}
3、注册service
3.1、修改CoreModule,在addQueryService加我们所需的service
classes.add(LogsFromEsQueryService.class);
3.2、修改CoreModuleProvider注册servcie,prepare方法加
this.registerServiceImplementation(LogsFromEsQueryService.class, new LogsFromEsQueryService(getManager()));
3.3、LogsFromEsQueryService
public class LogsFromEsQueryService implements Service {
private final ModuleManager moduleManager;
public LogsFromEsQueryService(ModuleManager moduleManager) {
this.moduleManager = moduleManager;
}
public List<EsData> esLogs(final String tid, final String span) throws IOException {
List<EsData> esLogs = new ArrayList<>();
Iterator<SearchHit> searchHitIterator = data.iterator();
while (searchHitIterator.hasNext()) {
SearchHit searchHit = searchHitIterator.next();
final Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
EsData esData = new EsData();
esData.setMessage((String) sourceAsMap.get(queryField));
Map<String,String> map = (Map<String, String>) sourceAsMap.get("beat");
esData.setHostName(map.get("hostname"));
esLogs.add(esData);
}
return esLogs;
}
}
4、webUi修改
4.1、修改trace-detail.vue,加想添加功能点的入口
<span class="link-hover" style="margin-left: 20px;font-weight: 800;">
<a :href="'/eslog?tid='+current.traceIds[0]+'&span='+handleSpan()" target="_blank">查看业务日志</a>
</span>
private handleSpan() {
const strSpans = new Set();
let spanStr = '';
this.spans.forEach( (spanId) => {
strSpans.add(spanId.serviceCode);
});
strSpans.forEach((spanId) => {
spanStr += spanId + ',';
});
return spanStr.substring(0, spanStr.length - 1);
}
4.2、展示页面logs.vue
<template>
<div class="rk-trace-t flex-v">
<div class="rk-trace-t-tool flex-h">
</div>
<div class="rk-trace-t-wrapper scroll_hide">
<table class="rk-trace-t">
<thead class="rk-trace-tr cp">
<td class="rk-trace-td" style="font-weight: bold;font-size: 25px;width:10%;">HOST</td>
<td class="rk-trace-td" style="font-weight: bold;font-size: 25px;">MESSAGE</td>
</thead>
<tr class="rk-trace-tr cp" v-for="log in logs">
<td class="rk-trace-td">{{ log.hostName }}</td>
<td class="rk-trace-td">{{ log.message }}</td>
</tr>
</table>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import { Component } from 'vue-property-decorator';
import axios, { AxiosResponse } from 'axios';
import {cancelToken} from '@/utils/cancelToken';
interface TraceInfo {
message: string;
hostName: string;
}
interface TraceData {
data: [String]
}
@Component
export default class Logs extends Vue {
private traceData: TraceInfo = {
message: '',
hostName: '',
};
private logs = [] as any;
private spans = {};
private created() {
axios.post('/graphql', {
query: `query esLogs($tid: String!,$span: String!){
esLogs(tid: $tid,span: $span){
message
hostName
}
}`,
variables: {
tid: this.$route.query.tid,
span: this.$route.query.span,
},
},
{ cancelToken: cancelToken() },
)
.then((res: AxiosResponse) => {
if ("" == res.data.data.esLogs) {
this.logs= [{"message":"请确认日志组件是否接入skywalking ","hostName":"未查到相关数据"}];
} else {
this.logs = res.data.data.esLogs;
}
})
.catch((error: EvalError) => {
console.log(error.message)
});
}
}
</script>
<style lang="scss" scoped>
.rk-trace-detail {
flex-shrink: 0;
height: 100%;
width: 75%;
overflow-y: auto;
.rk-btn.ghost {
background: rgba(0, 0, 0, 0.5);
}
}
</style>