diff --git a/zlt-business/search-center/search-client/src/main/java/com/central/search/model/SearchDto.java b/zlt-business/search-center/search-client/src/main/java/com/central/search/model/SearchDto.java index 71f24ebe68a600b5a53d1dec8b366aebe6b54f2a..e1a065305f86dff265b1d4c655c40db19d64ae7d 100644 --- a/zlt-business/search-center/search-client/src/main/java/com/central/search/model/SearchDto.java +++ b/zlt-business/search-center/search-client/src/main/java/com/central/search/model/SearchDto.java @@ -2,8 +2,6 @@ package com.central.search.model; import lombok.Data; import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; import java.io.Serializable; @@ -31,6 +29,10 @@ public class SearchDto implements Serializable { * 排序字段 */ private String sortCol; + /** + * 排序顺序 + */ + private String sortOrder = "DESC"; /** * 是否显示高亮 */ diff --git a/zlt-business/search-center/search-server/src/main/java/com/central/search/service/impl/SearchServiceImpl.java b/zlt-business/search-center/search-server/src/main/java/com/central/search/service/impl/SearchServiceImpl.java index 7ce6b6c38f9d38c72376be6257c2bf464aaccf68..b0395c8e5ae731530c871b19814da4b76e0ed85c 100644 --- a/zlt-business/search-center/search-server/src/main/java/com/central/search/service/impl/SearchServiceImpl.java +++ b/zlt-business/search-center/search-server/src/main/java/com/central/search/service/impl/SearchServiceImpl.java @@ -35,7 +35,7 @@ public class SearchServiceImpl implements ISearchService { public PageResult strQuery(String indexName, SearchDto searchDto) throws IOException { return SearchBuilder.builder(client, indexName) .setStringQuery(searchDto.getQueryStr()) - .addSort(searchDto.getSortCol(), SortOrder.DESC) + .addSort(searchDto.getSortCol(), searchDto.getSortOrder()) .setIsHighlight(searchDto.getIsHighlighter()) .getPage(searchDto.getPage(), searchDto.getLimit()); } diff --git a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java index 4fcac4ffd90bdcc60a21f0a467b577bc3e64dea0..ba2521a339899bcfa815ab5109825a927ed55a7a 100644 --- a/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java +++ b/zlt-commons/zlt-elasticsearch-spring-boot-starter/src/main/java/com/central/es/utils/SearchBuilder.java @@ -51,6 +51,10 @@ public class SearchBuilder { * 高亮后缀 */ private static final String HIGHLIGHTER_POST_TAGS = ""; + /** + * 排序顺序 + */ + private static final String SORT_ORDER_ASC = "ASC"; private SearchRequest searchRequest; private SearchSourceBuilder searchBuilder; @@ -144,9 +148,15 @@ public class SearchBuilder { * @param field 排序字段 * @param order 顺序方向 */ - public SearchBuilder addSort(String field, SortOrder order) { + public SearchBuilder addSort(String field, String order) { if (StrUtil.isNotEmpty(field) && order != null) { - searchBuilder.sort(field, order); + SortOrder so; + if (SORT_ORDER_ASC.equals(order)) { + so = SortOrder.ASC; + } else { + so = SortOrder.DESC; + } + searchBuilder.sort(field, so); } return this; } diff --git a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java index 0c5ccf29a221ce84b44ac75575f3fe6c7fe2d826..d9bf610f7e39df2cdb299642a7012e25f7d886cc 100644 --- a/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java +++ b/zlt-commons/zlt-log-spring-boot-starter/src/main/java/com/central/log/trace/MDCTraceUtils.java @@ -25,10 +25,6 @@ public class MDCTraceUtils { * 块id的名称 */ public static final String KEY_SPAN_ID = "spanId"; - /** - * 父块id的名称 - */ - public static final String KEY_PARENT_ID = "parentId"; /** * 日志链路追踪id信息头 @@ -38,10 +34,6 @@ public class MDCTraceUtils { * 日志链路块id信息头 */ public static final String SPAN_ID_HEADER = "x-spanId-header"; - /** - * 日志链路父块id信息头 - */ - public static final String PARENT_ID_HEADER = "x-parentId-header"; /** * filter的优先级,值越低越优先 diff --git a/zlt-monitor/log-center/src/main/java/com/central/log/controller/SysLogController.java b/zlt-monitor/log-center/src/main/java/com/central/log/controller/SysLogController.java index e7e151a841d89d4508ee4f993ace9974e76d5868..1afd8af1b4231f3087df748e2e1ef742bf509875 100644 --- a/zlt-monitor/log-center/src/main/java/com/central/log/controller/SysLogController.java +++ b/zlt-monitor/log-center/src/main/java/com/central/log/controller/SysLogController.java @@ -1,16 +1,20 @@ package com.central.log.controller; import com.central.common.model.PageResult; +import com.central.log.model.TraceLog; +import com.central.log.service.TraceLogService; import com.central.search.client.service.IQueryService; import com.central.search.model.SearchDto; import com.fasterxml.jackson.databind.JsonNode; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import javax.annotation.Resource; +import java.util.*; + /** * 系统日志 * @@ -18,19 +22,43 @@ import org.springframework.web.bind.annotation.RestController; */ @RestController public class SysLogController { - @Autowired + /** + * 系统日志索引名 + */ + private static final String SYS_LOG_INDEXNAME = "sys-log-*"; + + @Resource private IQueryService queryService; + @Resource + private TraceLogService traceLogService; + @ApiOperation(value = "系统日志全文搜索列表") @ApiImplicitParams({ @ApiImplicitParam(name = "page", value = "分页起始位置", required = true, dataType = "Integer"), @ApiImplicitParam(name = "limit", value = "分页结束位置", required = true, dataType = "Integer"), - @ApiImplicitParam(name = "queryStr", value = "搜索关键字", dataType = "String") + @ApiImplicitParam(name = "queryStr", value = "搜索关键字", dataType = "String"), + @ApiImplicitParam(name = "sortCol", value = "排序字段", dataType = "String"), + @ApiImplicitParam(name = "sortOrder", value = "排序顺序", dataType = "String"), + @ApiImplicitParam(name = "isHighlighter", value = "是否显示高亮", dataType = "String") }) @GetMapping(value = "/sysLog") - public PageResult getPage(SearchDto searchDto) { - searchDto.setIsHighlighter(true); - searchDto.setSortCol("timestamp"); - return queryService.strQuery("sys-log-*", searchDto); + public PageResult sysLog(SearchDto searchDto) { + return queryService.strQuery(SYS_LOG_INDEXNAME, searchDto); + } + + @ApiOperation(value = "系统日志链路列表") + @ApiImplicitParams({ + @ApiImplicitParam(name = "queryStr", value = "搜索关键字", dataType = "String"), + @ApiImplicitParam(name = "sortCol", value = "排序字段", dataType = "String"), + @ApiImplicitParam(name = "sortOrder", value = "排序顺序", dataType = "String"), + @ApiImplicitParam(name = "isHighlighter", value = "是否显示高亮", dataType = "String") + }) + @GetMapping(value = "/traceLog") + public PageResult traceLog(SearchDto searchDto) { + PageResult pageResult = queryService.strQuery(SYS_LOG_INDEXNAME, searchDto); + List jsonNodeList = pageResult.getData(); + List logList = traceLogService.transTraceLog(jsonNodeList); + return PageResult.builder().data(logList).code(0).count((long) logList.size()).build(); } } diff --git a/zlt-monitor/log-center/src/main/java/com/central/log/model/TraceLog.java b/zlt-monitor/log-center/src/main/java/com/central/log/model/TraceLog.java new file mode 100644 index 0000000000000000000000000000000000000000..ee508ed3cd5337cf3f8f9c31d02731c40d28f407 --- /dev/null +++ b/zlt-monitor/log-center/src/main/java/com/central/log/model/TraceLog.java @@ -0,0 +1,24 @@ +package com.central.log.model; + +import lombok.Getter; +import lombok.Setter; + +/** + * 日志链路对象 + * + * @author zlt + * @version 1.0 + * @date 2022/1/27 + *

+ * Blog: https://zlt2000.gitee.io + * Github: https://github.com/zlt2000 + */ +@Setter +@Getter +public class TraceLog { + private String spanId; + private String parentId; + private String appName; + private String serverIp; + private String serverPort; +} diff --git a/zlt-monitor/log-center/src/main/java/com/central/log/service/TraceLogService.java b/zlt-monitor/log-center/src/main/java/com/central/log/service/TraceLogService.java new file mode 100644 index 0000000000000000000000000000000000000000..f7c094d1bc0a52b79efac609a1cd95f283d57cb8 --- /dev/null +++ b/zlt-monitor/log-center/src/main/java/com/central/log/service/TraceLogService.java @@ -0,0 +1,61 @@ +package com.central.log.service; + +import cn.hutool.core.util.StrUtil; +import com.central.common.utils.JsonUtil; +import com.central.log.model.TraceLog; +import com.fasterxml.jackson.databind.JsonNode; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 日志链路service + * + * @author zlt + * @version 1.0 + * @date 2022/1/27 + *

+ * Blog: https://zlt2000.gitee.io + * Github: https://github.com/zlt2000 + */ +@Service +public class TraceLogService { + public List transTraceLog(List jsonNodeList) { + List logList = new ArrayList<>(); + Set logSet = new HashSet<>(); + jsonNodeList.forEach(e -> { + TraceLog log = JsonUtil.toObject(e, TraceLog.class); + String spanId = log.getSpanId(); + if (StrUtil.isNotEmpty(spanId)) { + if (spanId.length() == 1) { + log.setParentId("-1"); + } else { + log.setParentId(spanId.substring(0, spanId.length() - 2)); + } + if (checkLog(genLogKey(log), logSet)) { + logList.add(log); + } + } + }); + return logList; + } + + /** + * 通过集合来去重 + */ + private boolean checkLog(String logKey, Set logSet) { + if (logSet.contains(logKey)) { + return false; + } else { + logSet.add(logKey); + return true; + } + } + + private String genLogKey(TraceLog log) { + return StrUtil.format("{}_{}_{}_{}", log.getAppName(), log.getSpanId(), log.getServerIp(), log.getServerPort()); + } +} diff --git a/zlt-web/back-web/src/main/resources/static/pages/log/sysLog.html b/zlt-web/back-web/src/main/resources/static/pages/log/sysLog.html index b57b6d58f7368e08d3128f85b20e384735e11944..4adf1419f603a80d22cd1279204e1cdb07963f27 100644 --- a/zlt-web/back-web/src/main/resources/static/pages/log/sysLog.html +++ b/zlt-web/back-web/src/main/resources/static/pages/log/sysLog.html @@ -29,33 +29,66 @@ layui.use(['form', 'table', 'util', 'config', 'admin', 'upload'], function () { let table = layui.table; let config = layui.config; - let util = layui.util; + let admin = layui.admin; // 渲染表格 table.render({ elem: '#sysLog-table', - url: config.base_server + 'api-log/sysLog', + url: config.base_server + 'api-log/sysLog?sortCol=timestamp&isHighlighter=true', method: 'GET', headers:{'Authorization': 'Bearer ' + config.getToken().access_token}, page: true, cols: [[ {type: 'numbers'}, { - field: 'timestamp', width: 200, sort: true, templet: function (d) { - return util.toDateString(d.timestamp, 'yyyy-MM-dd HH:mm:ss'); - }, title: '日志时间' + field: 'timestamp', width: 180, sort: true, templet: function (d) { + let newDate = Date.parse(d.timestamp); + newDate = new Date(newDate); + let yyyy = newDate.getFullYear(); + let MM = (newDate.getMonth()+1); + let dd = newDate.getDate(); + let hh = newDate.getHours()<10 ? "0"+newDate.getHours() : newDate.getHours(); + let mm = newDate.getMinutes()<10 ? "0"+newDate.getMinutes() : newDate.getMinutes(); + let ss = newDate.getSeconds()<10 ? "0"+newDate.getSeconds() : newDate.getSeconds(); + let SSS = newDate.getMilliseconds(); + return yyyy+"-"+MM+"-"+dd+" "+hh+":"+mm+":"+ss+"."+SSS; + }, title: '时间' }, {field: 'message', sort: true, title: '日志信息', width: 350}, - {field: 'logLevel', sort: true, title: '日志级别', width: 100}, + {field: 'logLevel', sort: true, title: '日志级别', width: 110}, {field: 'appName', sort: true, title: '应用名', width: 120}, - {field: 'serverIp', sort: true, title: '服务ip', width: 130}, - {field: 'serverPort', sort: true, title: '服务端口', width: 100}, - {field: 'threadName', sort: true, title: '线程名', width: 150}, + {field: 'traceId', sort: false, title: '追踪id', width: 180, templet: function (d) { + if (d.traceId){ + return ''+d.traceId+''; + } else { + return ''; + } + }}, + {field: 'spanId', sort: false, title: 'spanId', width: 80}, {field: 'classname', sort: true, title: '类名', width: 250}, - {field: 'traceId', sort: true, title: '链路追踪id', width: 200} + {field: 'threadName', sort: true, title: '线程名', width: 150}, + {field: 'serverIp', sort: true, title: '服务ip', width: 130}, + {field: 'serverPort', sort: true, title: '服务端口', width: 110} ]] }); + // 工具条点击事件 + table.on('tool(sysLog-table)', function (obj) { + if (obj.event === 'traceLog') { + showTraceLog(obj.data.traceId); + } + }); + + //显示表单弹窗 + let showTraceLog = function (traceId) { + admin.putTempData('traceId', traceId); + admin.popupCenter({ + title: '日志链路', + area: '670px', + path: 'pages/log/traceLog.html' + }); + }; + // 搜索按钮点击事件 $('#sysLog-btn-search').click(function () { let key = $('#sysLog-search-key').val(); @@ -63,7 +96,9 @@ if (key != '_all' && value) { value = key + ':' + value; } - table.reload('sysLog-table', {where: {queryStr: value}}); + table.reload('sysLog-table', { + where: {queryStr: value} + }); }); }); \ No newline at end of file diff --git a/zlt-web/back-web/src/main/resources/static/pages/log/traceLog.html b/zlt-web/back-web/src/main/resources/static/pages/log/traceLog.html new file mode 100644 index 0000000000000000000000000000000000000000..9b62f01a2a4c9f356723c7faa369e06152a6656f --- /dev/null +++ b/zlt-web/back-web/src/main/resources/static/pages/log/traceLog.html @@ -0,0 +1,45 @@ + +
+ + \ No newline at end of file diff --git a/zlt-web/back-web/src/main/resources/static/pages/system/menus.html b/zlt-web/back-web/src/main/resources/static/pages/system/menus.html index d678b13fb199d6cc1c2a31cf0d3141fb234e9ad9..23d3861eed7f81e89cdf98122d9500c48844fec0 100644 --- a/zlt-web/back-web/src/main/resources/static/pages/system/menus.html +++ b/zlt-web/back-web/src/main/resources/static/pages/system/menus.html @@ -39,14 +39,7 @@ let form = layui.form; // 渲染表格 - var renderTable = function (param) { - if (param) { - param.access_token = config.getToken().access_token; - } else { - param = { - access_token: config.getToken().access_token - }; - } + var renderTable = function (tenantId) { treetable.render({ treeColIndex: 1, treeSpid: -1, @@ -54,7 +47,10 @@ treePidName: 'parentId', elem: '#menus-table', url: config.base_server + 'api-user/menus/findAlls', - where: param, + where: { + access_token: config.getToken().access_token, + tenantId: tenantId + }, page: false, cols: [[ {type: 'numbers'}, @@ -79,7 +75,7 @@ ]] }); }; - renderTable({tenantId: config.clientId}); + renderTable(config.clientId); // 获取应用列表 layer.load(2); @@ -117,7 +113,7 @@ layer.closeAll('loading'); if (0 === data.resp_code) { layer.msg(data.resp_msg, {icon: 1, time: 500}); - renderTable({tenantId: tenantId}); + renderTable(tenantId); } else { layer.msg(data.resp_msg, {icon: 2, time: 500}); } @@ -143,7 +139,7 @@ title: title, path: 'pages/system/menus_form.html', finish: function () { - renderTable({tenantId: tenantId}); + renderTable(tenantId); } }); }; @@ -186,7 +182,7 @@ // 应用下来框点击事件 form.on('select(menu_clients)', function(data){ - renderTable({tenantId: data.value}); + renderTable(data.value); }); }); \ No newline at end of file