fix:lucene日志地址

This commit is contained in:
zhangzq
2026-06-18 14:39:20 +08:00
parent 7e1bacded8
commit b14042dd68
16 changed files with 247 additions and 66 deletions

View File

@@ -27,7 +27,8 @@ import org.nl.common.utils.IPUtil;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.RequestHolder;
import org.nl.common.utils.SecurityUtils;
import org.nl.config.lucene.LuceneAppender;
import org.nl.wms.system_manage.service.logserver.lucene.BaseCode;
import org.nl.wms.system_manage.service.logserver.lucene.LuceneAppender;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
@@ -57,8 +58,8 @@ public class LogAspect {
*
* @param joinPoint join point for advice
*/
@Around("@annotation(logInfo)")
public Object logAround(ProceedingJoinPoint joinPoint,org.nl.common.logging.annotation.Log logInfo) throws Throwable {
@Around("@annotation(logAnno)")
public Object logAround(ProceedingJoinPoint joinPoint,org.nl.common.logging.annotation.Log logAnno) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
@@ -69,6 +70,7 @@ public class LogAspect {
MDC.put("requestMethod",url);
MDC.put("requestIp", requestIp);
MDC.put("requestTime", DateUtil.now());
LuceneAppender.traceIdTL.set(BaseCode.intToChars(IdUtil.getLongId()));
Object result = null;
long comming = System.currentTimeMillis();
try {
@@ -97,6 +99,7 @@ public class LogAspect {
}finally {
log.info("[--response--][请求接口:{} 执行结束][耗时:{}s]",url,(System.currentTimeMillis() - comming)/1000);
MDC.clear();
LuceneAppender.traceIdTL.remove();
}
return result;
}

View File

@@ -4,6 +4,7 @@ package org.nl.wms.ext_manage.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.common.logging.annotation.Log;
import org.nl.wms.ext_manage.service.dto.StructLineOfflineDTO;
import org.nl.wms.ext_manage.service.impl.StructOfflineService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -33,6 +34,7 @@ public class MesStructLineController {
*/
@PostMapping("/offline")
@SaIgnore
@Log
public ResponseEntity<Object> confirm(@RequestBody StructLineOfflineDTO structLineOffline) {
structOfflineTask.offline(structLineOffline);
return new ResponseEntity<>(HttpStatus.OK);

View File

@@ -1,4 +1,4 @@
package org.nl.wms.system_manage.controller.lucence;
package org.nl.wms.system_manage.controller.log;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.extern.slf4j.Slf4j;
@@ -18,7 +18,7 @@ import org.springframework.web.bind.annotation.*;
*/
@RestController
@RequestMapping("/api/esLog")
@RequestMapping("/api/lucene")
@Slf4j
public class LuceneLogController {

View File

@@ -13,8 +13,8 @@ public class LogQuery {
/**
* 创建时间范围查询
*/
private Date startTime;
private Date endTime;
private String startTime;
private String endTime;
/**
* 追踪id
*/

View File

@@ -8,6 +8,7 @@ import cn.hutool.db.PageResult;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
@@ -17,13 +18,15 @@ import org.apache.lucene.search.*;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;
import org.nl.common.exception.BadRequestException;
import org.nl.config.lucene.LuceneAppender;
import org.nl.wms.system_manage.service.logserver.lucene.LuceneAppender;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.wltea.analyzer.lucene.IKAnalyzer;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
@@ -83,20 +86,27 @@ public class LuceneLogServiceImpl implements LuceneLogService {
// 创建排序对象,需要排序字段SortField参数字段的名称、字段的类型、是否反转如果是false升序。true降序
BooleanQuery.Builder booleanQueryBuilder = new BooleanQuery.Builder();
//时间范围查询
Date startDate = logQuery.getStartTime();
Date endDate = logQuery.getEndTime();
if (startDate == null){
Calendar calendar=Calendar.getInstance();
calendar.set(1970, 0, 1);
startDate = calendar.getTime(); }
if (endDate == null){ endDate = new DateTime(); }
String startTimeStr = logQuery.getStartTime();
String endTimeStr = logQuery.getEndTime();
LocalDateTime startDateTime;
LocalDateTime endDateTime;
if (StringUtils.isEmpty(startTimeStr)) {
startDateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0);
} else {
startDateTime = LocalDateTime.parse(startTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 假设格式
}
if (StringUtils.isEmpty(endTimeStr)) {
endDateTime = LocalDateTime.now();
} else {
endDateTime = LocalDateTime.parse(endTimeStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
}
String startFormatted = startDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
String endFormatted = endDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS"));
TermRangeQuery termRangeQuery = new TermRangeQuery(
"requestTime",
new BytesRef(DateUtil.format(startDate, "yyyy-MM-dd HH:mm:ss.SSS")),
new BytesRef(DateUtil.format(endDate, "yyyy-MM-dd HH:mm:ss.SSS")), true, true);
new BytesRef(startFormatted),
new BytesRef(endFormatted), true, true);
booleanQueryBuilder.add(termRangeQuery,BooleanClause.Occur.MUST);
// 字段之间的与或非关系MUST表示andMUST_NOT表示notSHOULD表示or有几个fields就必须有几个clauses
if (ObjectUtil.isNotEmpty(logQuery.getTraceId())){
TermQuery termQuery = new TermQuery(new Term("traceId", logQuery.getTraceId()));

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
/**
* @author ldjun
* @version 1.0
@@ -26,7 +26,7 @@ public class AsyncLuceneAppender extends AspectLogbackAsyncAppender {
if (mdcPropertyMap.getClass().getName().contains("SynchronizedMap")){
mdcPropertyMap.put("traceId",traceId);
}
MDC.clear();
}
super.append(event);
}
}

View File

@@ -0,0 +1,33 @@
package org.nl.wms.system_manage.service.logserver.lucene;
/*
* @author ZZQ
* @Date 2023/2/9 2:54 下午
*/
public class BaseCode {
static final char[] MySerials = new char[]{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p','q','r','s','t','u','v','w','x','y','z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q','R','S','T','U','V','W','X','Y','Z'};
public static final String intToChars(long n){
String s = "";
if (n == 0) {
s = "0";
}
while (n != 0) {
int i = (int) (n % MySerials.length);
char c = MySerials[i];
s = c + s;
n = n / MySerials.length;
}
for (int x = s.length();x<5;x++){
s="0"+s;
}
return s;
}
}

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
/**
* @Author: lyd

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
/**
* @author ldjun
* @version 1.0

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
import java.util.ArrayList;

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;

View File

@@ -1,4 +1,4 @@
package org.nl.config.lucene;
package org.nl.wms.system_manage.service.logserver.lucene;
/*
* @author ZZQ

View File

@@ -4,7 +4,7 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.search.Query;
import org.nl.config.lucene.LuceneAppender;
import org.nl.wms.system_manage.service.logserver.lucene.LuceneAppender;
import org.nl.wms.system_manage.service.param.ISysParamService;
import org.nl.wms.system_manage.service.param.dao.Param;
import org.springframework.beans.factory.annotation.Autowired;

View File

@@ -60,7 +60,7 @@
<queueSize>500</queueSize>
<appender-ref ref="ErpLogFile"/>
</appender>
<appender name="luceneAppender" class="org.nl.config.lucene.LuceneAppender" >
<appender name="luceneAppender" class="org.nl.wms.system_manage.service.logserver.lucene.LuceneAppender" >
<properties>
<property>
<name>system</name>
@@ -92,7 +92,7 @@
</property>
</properties>
</appender>
<appender name="asyncLuceneAppender" class="org.nl.config.lucene.AsyncLuceneAppender">
<appender name="asyncLuceneAppender" class="org.nl.wms.system_manage.service.logserver.lucene.AsyncLuceneAppender">
<appender-ref ref="luceneAppender" />
<queueSize>512</queueSize>
</appender>

View File

@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function getLogData(param) {
return request({
url: 'api/lucene/getAll',
url: 'api/lucene/query',
method: 'post',
data: param
})
@@ -16,14 +16,14 @@ export function getTagName() {
}
export function deleteAllLog() {
return request({
url: 'api/lucene/deleteAllLog',
url: 'api/lucene/clearLogs',
method: 'post'
})
}
export function labelsValues() {
return request({
url: 'api/loki/labels/values',
url: 'api/lucene/labels/values',
method: 'get'
})
}

View File

@@ -7,24 +7,9 @@
label-width="=100px"
label-suffix=":"
>
<el-form-item :label="$t('Log.label')">
<el-select
v-model="query.label"
clearable
size="mini"
:placeholder="$t('Log.label')"
style="width: 240px;"
>
<el-option
v-for="item in tagList"
:label="item"
:value="item"
/>
</el-select>
</el-form-item>
<el-form-item :label="$t('Log.level')">
<el-select
v-model="query.level"
v-model="query.logLevel"
clearable
size="mini"
:placeholder="$t('Log.level')"
@@ -36,6 +21,14 @@
/>
</el-select>
</el-form-item>
<el-form-item label="Request Method">
<el-input
v-model="query.requestMethod"
clearable
size="mini"
placeholder="GET/POST/PUT/DELETE"
/>
</el-form-item>
<el-form-item :label="$t('Log.search')">
<el-input
v-model="query.message"
@@ -46,7 +39,7 @@
</el-form-item>
<el-form-item :label="$t('Log.link_id')">
<el-input
v-model="query.tlogTraceId"
v-model="query.traceId"
clearable
size="mini"
:placeholder="$t('Log.link_id_msg')"
@@ -71,9 +64,17 @@
</div>
<!--表格渲染-->
<el-card shadow="hover" style="width: 100%" class="log-warpper">
<div style="width: 100%">
<div v-for="(log, index) in logs" :key="index">
<div style="margin-bottom: 5px; font-size: 14px;" v-html="log" />
<div class="log-list">
<div v-for="(log, index) in logs" :key="index" class="log-item">
<div class="log-meta">
<span v-if="log.requestTime" class="log-time log-badge log-badge-time">{{ log.requestTime }}</span>
<span class="log-level" :class="`log-level-${getLevelClass(log.logLevel)}`">{{ log.logLevel || 'UNKNOWN' }}</span>
<span v-if="log.requestIp" class="log-ip log-badge log-badge-ip">IP: {{ log.requestIp }}</span>
<span v-if="log.requestMethod" class="log-method log-badge log-badge-method">{{ log.requestMethod }}</span>
<span v-if="log.traceId && log.traceId.trim()" class="log-trace log-badge log-badge-trace">traceId: {{ log.traceId }}</span>
<span v-if="log.thread" class="log-thread log-badge log-badge-thread">{{ log.thread }}</span>
</div>
<div class="log-message" v-html="log.messageHtml" />
</div>
</div>
</el-card>
@@ -120,8 +121,12 @@ export default {
logs: [],
tagList: [],
query: {
tlogTraceId: '',
traceId: '',
requestMethod: '',
message: '',
logLevel: '',
startTime: '',
endTime: '',
page: 0,
size: 100,
total: 0,
@@ -131,7 +136,7 @@ export default {
},
created() {
this.queryData()
this.getTagList()
// this.getTagList()
},
methods: {
handleSizeChange(val) {
@@ -142,25 +147,44 @@ export default {
this.query.page = val
this.queryData()
},
getTagList() {
luceneOperation.getTagName().then(res => {
this.tagList = res
})
getLevelClass(level) {
const normalizedLevel = (level || '').toUpperCase()
const levelMap = {
ERROR: 'error',
WARN: 'warn',
INFO: 'info',
DEBUG: 'debug'
}
return levelMap[normalizedLevel] || 'default'
},
formatLogMessage(item, ansi_up) {
const rawMessage = item && typeof item === 'object'
? item.message || JSON.stringify(item)
: String(item || '')
return {
requestTime: item && item.requestTime,
requestIp: item && item.requestIp,
requestMethod: item && item.requestMethod,
logLevel: item && item.logLevel,
thread: item && item.thread,
traceId: item && item.traceId,
messageHtml: ansi_up.ansi_to_html(rawMessage)
}
},
queryData() {
if (this.query.createTime) {
if (this.query.createTime && this.query.createTime.length === 2) {
this.query.startTime = this.query.createTime[0]
this.query.endTime = this.query.createTime[1]
} else {
this.query.startTime = ''
this.query.endTime = ''
}
luceneOperation.getLogData(this.query).then(res => {
this.logs = [] // 清空
this.logs = []
var ansi_up = new AnsiUp()
// 数据初始化
for (const i in res.content) {
this.logs[i] = ansi_up.ansi_to_html(res.content[i])
}
// this.logs = res.content
this.query.total = res.totalElements
const page = Array.isArray(res.page) ? res.page : []
this.logs = page.map(item => this.formatLogMessage(item, ansi_up))
this.query.total = res.total || 0
})
}
}
@@ -168,5 +192,114 @@ export default {
</script>
<style scoped>
.log-list {
width: 100%;
}
.log-item {
margin-bottom: 10px;
padding: 10px 12px;
border-radius: 6px;
background: #fafafa;
border: 1px solid #ebeef5;
}
.log-meta {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
margin-bottom: 6px;
font-size: 12px;
color: #606266;
}
.log-badge {
display: inline-flex;
align-items: center;
padding: 0 8px;
line-height: 22px;
border-radius: 11px;
border: 1px solid transparent;
}
.log-time,
.log-ip,
.log-method,
.log-thread,
.log-trace {
line-height: 20px;
}
.log-badge-time {
color: #606266;
background: #f4f4f5;
border-color: #dcdfe6;
}
.log-badge-ip {
color: #7c4dff;
background: #f3edff;
border-color: #d9c8ff;
}
.log-badge-method {
color: #0f766e;
background: #ecfdf5;
border-color: #b7ebd3;
font-weight: 500;
}
.log-badge-thread {
color: #8e44ad;
background: #f8f0ff;
border-color: #e2cfff;
}
.log-badge-trace {
color: #c05621;
background: #fff7ed;
border-color: #fbd38d;
}
.log-level {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 56px;
padding: 0 8px;
line-height: 20px;
border-radius: 10px;
font-size: 12px;
font-weight: 600;
color: #fff;
}
.log-level-error {
background: #f56c6c;
}
.log-level-warn {
background: #e6a23c;
}
.log-level-info {
background: #409eff;
}
.log-level-debug {
background: #909399;
}
.log-level-default {
background: #67c23a;
}
.log-message {
font-size: 14px;
line-height: 1.7;
color: #303133;
word-break: break-word;
white-space: pre-wrap;
}
</style>