package com.emergencyrepair.system.log;
|
|
import com.emergencyrepair.common.audit.CurrentUserContext;
|
import com.emergencyrepair.system.entity.SysErrorLog;
|
import com.emergencyrepair.system.mapper.SysErrorLogMapper;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.StringUtils;
|
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.PrintWriter;
|
import java.io.StringWriter;
|
import java.time.LocalDateTime;
|
import java.util.List;
|
|
/**
|
* Persists unhandled server exceptions so administrators can inspect runtime bugs.
|
*/
|
@Component
|
@RequiredArgsConstructor
|
public class ErrorLogRecorder {
|
private static final int MAX_MESSAGE_LENGTH = 2000;
|
private static final int MAX_STACK_LENGTH = 60000;
|
|
private final SysErrorLogMapper errorLogMapper;
|
private final JdbcTemplate jdbcTemplate;
|
|
public void record(Exception exception, HttpServletRequest request) {
|
if (exception == null) {
|
return;
|
}
|
try {
|
String username = CurrentUserContext.get();
|
Long userId = resolveUserId(username);
|
SysErrorLog log = new SysErrorLog();
|
log.setUserId(userId);
|
log.setUserName(username);
|
log.setNickName(resolveNickName(userId));
|
log.setModule(resolveModule(request));
|
log.setRequestMethod(request == null ? null : limit(request.getMethod(), 10));
|
log.setRequestUri(request == null ? null : limit(request.getRequestURI(), 500));
|
log.setExceptionType(limit(exception.getClass().getName(), 300));
|
log.setMessage(limit(resolveMessage(exception), MAX_MESSAGE_LENGTH));
|
log.setStackTrace(limit(stackTrace(exception), MAX_STACK_LENGTH));
|
log.setErrorTime(LocalDateTime.now());
|
errorLogMapper.insert(log);
|
} catch (Exception ignored) {
|
// Error logging must never interfere with the original error response.
|
}
|
}
|
|
private Long resolveUserId(String username) {
|
if (!StringUtils.hasText(username)) {
|
return null;
|
}
|
List<Long> ids = jdbcTemplate.query(
|
"SELECT USER_ID FROM CSICZB_ZB.SYS_USER WHERE USER_NAME = ? AND (DEL_FLAG = '0' OR DEL_FLAG IS NULL)",
|
new Object[]{username}, (rs, rowNum) -> rs.getLong(1));
|
return ids.isEmpty() ? null : ids.get(0);
|
}
|
|
private String resolveNickName(Long userId) {
|
if (userId == null) {
|
return null;
|
}
|
List<String> names = jdbcTemplate.query(
|
"SELECT NICK_NAME FROM CSICZB_ZB.SYS_USER WHERE USER_ID = ?",
|
new Object[]{userId}, (rs, rowNum) -> rs.getString(1));
|
return names.isEmpty() ? null : names.get(0);
|
}
|
|
private String resolveMessage(Exception exception) {
|
String message = exception.getMessage();
|
return StringUtils.hasText(message) ? message : exception.getClass().getSimpleName();
|
}
|
|
private String stackTrace(Exception exception) {
|
StringWriter writer = new StringWriter();
|
exception.printStackTrace(new PrintWriter(writer));
|
return writer.toString();
|
}
|
|
private String resolveModule(HttpServletRequest request) {
|
if (request == null || !StringUtils.hasText(request.getRequestURI())) {
|
return "其他";
|
}
|
String uri = request.getRequestURI();
|
if (uri.startsWith("/api/faults") || uri.startsWith("/api/fault")) return "故障管理";
|
if (uri.startsWith("/api/work-orders") || uri.startsWith("/api/completion")) return "完工管理";
|
if (uri.startsWith("/api/acceptances")) return "完工验收";
|
if (uri.startsWith("/api/reports")) return "统计报表";
|
if (uri.startsWith("/api/system/users")) return "用户管理";
|
if (uri.startsWith("/api/system/roles")) return "角色管理";
|
if (uri.startsWith("/api/system/menu")) return "菜单管理";
|
if (uri.startsWith("/api/system/contractors")) return "承修单位管理";
|
if (uri.startsWith("/api/system")) return "系统管理";
|
return "其他";
|
}
|
|
private String limit(String value, int maxLength) {
|
if (value == null || value.length() <= maxLength) {
|
return value;
|
}
|
return value.substring(0, maxLength);
|
}
|
}
|