mirror of https://github.com/elunez/eladmin
				
				
				
			perf: 优化系统日志参数获取,优化在线用户Token管理,优化SQl日志打印
							parent
							
								
									7b2fa3c679
								
							
						
					
					
						commit
						fb422c6a9a
					
				| 
						 | 
				
			
			@ -133,13 +133,13 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
 | 
			
		|||
     */
 | 
			
		||||
    public static String getIp(HttpServletRequest request) {
 | 
			
		||||
        String ip = request.getHeader("x-forwarded-for");
 | 
			
		||||
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
            ip = request.getHeader("Proxy-Client-IP");
 | 
			
		||||
        }
 | 
			
		||||
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
            ip = request.getHeader("WL-Proxy-Client-IP");
 | 
			
		||||
        }
 | 
			
		||||
        if (ip == null || ip.length() == 0 || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
        if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
 | 
			
		||||
            ip = request.getRemoteAddr();
 | 
			
		||||
        }
 | 
			
		||||
        String comma = ",";
 | 
			
		||||
| 
						 | 
				
			
			@ -169,6 +169,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
 | 
			
		|||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取浏览器
 | 
			
		||||
     */
 | 
			
		||||
    public static String getBrowser(HttpServletRequest request) {
 | 
			
		||||
        UserAgent ua = UserAgentUtil.parse(request.getHeader("User-Agent"));
 | 
			
		||||
        String browser = ua.getBrowser().toString() + " " + ua.getVersion();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,6 +88,10 @@ public class LogAspect {
 | 
			
		|||
        sysLogService.save(getUsername(), StringUtils.getBrowser(request), StringUtils.getIp(request), (ProceedingJoinPoint)joinPoint, sysLog);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取用户名
 | 
			
		||||
     * @return /
 | 
			
		||||
     */
 | 
			
		||||
    public String getUsername() {
 | 
			
		||||
        try {
 | 
			
		||||
            return SecurityUtils.getCurrentUsername();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -35,8 +35,8 @@ import org.springframework.data.domain.Pageable;
 | 
			
		|||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestBody;
 | 
			
		||||
import org.springframework.web.bind.annotation.RequestParam;
 | 
			
		||||
import org.springframework.web.multipart.MultipartFile;
 | 
			
		||||
import javax.servlet.http.HttpServletRequest;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
| 
						 | 
				
			
			@ -50,9 +50,12 @@ import java.util.*;
 | 
			
		|||
@Service
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class SysLogServiceImpl implements SysLogService {
 | 
			
		||||
 | 
			
		||||
    private final LogRepository logRepository;
 | 
			
		||||
    private final LogErrorMapper logErrorMapper;
 | 
			
		||||
    private final LogSmallMapper logSmallMapper;
 | 
			
		||||
    // 定义敏感字段常量数组
 | 
			
		||||
    private static final String[] SENSITIVE_KEYS = {"password"};
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Object queryAll(SysLogQueryCriteria criteria, Pageable pageable) {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +84,8 @@ public class SysLogServiceImpl implements SysLogService {
 | 
			
		|||
        if (sysLog == null) {
 | 
			
		||||
            throw new IllegalArgumentException("Log 不能为 null!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 获取方法签名
 | 
			
		||||
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
 | 
			
		||||
        Method method = signature.getMethod();
 | 
			
		||||
        me.zhengjie.annotation.Log aopLog = method.getAnnotation(me.zhengjie.annotation.Log.class);
 | 
			
		||||
| 
						 | 
				
			
			@ -88,56 +93,64 @@ public class SysLogServiceImpl implements SysLogService {
 | 
			
		|||
        // 方法路径
 | 
			
		||||
        String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
 | 
			
		||||
 | 
			
		||||
        // 描述
 | 
			
		||||
        sysLog.setDescription(aopLog.value());
 | 
			
		||||
        
 | 
			
		||||
        // 获取参数
 | 
			
		||||
        JSONObject params = getParameter(method, joinPoint.getArgs());
 | 
			
		||||
 | 
			
		||||
        // 填充基本信息
 | 
			
		||||
        sysLog.setRequestIp(ip);
 | 
			
		||||
        sysLog.setAddress(StringUtils.getCityInfo(sysLog.getRequestIp()));
 | 
			
		||||
        sysLog.setMethod(methodName);
 | 
			
		||||
        sysLog.setUsername(username);
 | 
			
		||||
        sysLog.setParams(getParameter(method, joinPoint.getArgs()));
 | 
			
		||||
        // 记录登录用户,隐藏密码信息
 | 
			
		||||
        if(signature.getName().equals("login") && StringUtils.isNotEmpty(sysLog.getParams())){
 | 
			
		||||
            JSONObject obj = JSON.parseObject(sysLog.getParams());
 | 
			
		||||
            sysLog.setUsername(obj.getString("username"));
 | 
			
		||||
            sysLog.setParams(JSON.toJSONString(Dict.create().set("username", sysLog.getUsername())));
 | 
			
		||||
        }
 | 
			
		||||
        sysLog.setParams(JSON.toJSONString(params));
 | 
			
		||||
        sysLog.setBrowser(browser);
 | 
			
		||||
        sysLog.setDescription(aopLog.value());
 | 
			
		||||
 | 
			
		||||
        // 如果没有获取到用户名,尝试从参数中获取
 | 
			
		||||
        if(StringUtils.isBlank(sysLog.getUsername())){
 | 
			
		||||
            sysLog.setUsername(params.getString("username"));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 保存
 | 
			
		||||
        logRepository.save(sysLog);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据方法和传入的参数获取请求参数
 | 
			
		||||
     */
 | 
			
		||||
    private String getParameter(Method method, Object[] args) {
 | 
			
		||||
        List<Object> argList = new ArrayList<>();
 | 
			
		||||
    private JSONObject getParameter(Method method, Object[] args) {
 | 
			
		||||
        JSONObject params = new JSONObject();
 | 
			
		||||
        Parameter[] parameters = method.getParameters();
 | 
			
		||||
        for (int i = 0; i < parameters.length; i++) {
 | 
			
		||||
            // 过滤掉不能序列化的类型: MultiPartFile
 | 
			
		||||
            // 过滤掉 MultiPartFile
 | 
			
		||||
            if (args[i] instanceof MultipartFile) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            //将RequestBody注解修饰的参数作为请求参数
 | 
			
		||||
            // 过滤掉 HttpServletResponse
 | 
			
		||||
            if (args[i] instanceof HttpServletResponse) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // 过滤掉 HttpServletRequest
 | 
			
		||||
            if (args[i] instanceof HttpServletRequest) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            // 将RequestBody注解修饰的参数作为请求参数
 | 
			
		||||
            RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
 | 
			
		||||
            if (requestBody != null) {
 | 
			
		||||
                argList.add(args[i]);
 | 
			
		||||
            }
 | 
			
		||||
            //将RequestParam注解修饰的参数作为请求参数
 | 
			
		||||
            RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
 | 
			
		||||
            if (requestParam != null) {
 | 
			
		||||
                Map<String, Object> map = new HashMap<>(2);
 | 
			
		||||
                params.putAll((JSONObject) JSON.toJSON(args[i]));
 | 
			
		||||
            } else {
 | 
			
		||||
                String key = parameters[i].getName();
 | 
			
		||||
                if (!StringUtils.isEmpty(requestParam.value())) {
 | 
			
		||||
                    key = requestParam.value();
 | 
			
		||||
                }
 | 
			
		||||
                map.put(key, args[i]);
 | 
			
		||||
                argList.add(map);
 | 
			
		||||
                params.put(key, args[i]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (argList.isEmpty()) {
 | 
			
		||||
            return "";
 | 
			
		||||
        // 遍历敏感字段数组并替换值
 | 
			
		||||
        Set<String> keys = params.keySet();
 | 
			
		||||
        for (String key : SENSITIVE_KEYS) {
 | 
			
		||||
            if (keys.contains(key)) {
 | 
			
		||||
                params.put(key, "******");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return argList.size() == 1 ? JSON.toJSONString(argList.get(0)) : JSON.toJSONString(argList);
 | 
			
		||||
        // 返回参数
 | 
			
		||||
        return params;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -18,7 +18,6 @@ package me.zhengjie.modules.security.security;
 | 
			
		|||
import cn.hutool.core.date.DateField;
 | 
			
		||||
import cn.hutool.core.date.DateUtil;
 | 
			
		||||
import cn.hutool.core.util.IdUtil;
 | 
			
		||||
import cn.hutool.crypto.digest.DigestUtil;
 | 
			
		||||
import io.jsonwebtoken.*;
 | 
			
		||||
import io.jsonwebtoken.io.Decoders;
 | 
			
		||||
import io.jsonwebtoken.security.Keys;
 | 
			
		||||
| 
						 | 
				
			
			@ -47,7 +46,7 @@ public class TokenProvider implements InitializingBean {
 | 
			
		|||
    private JwtBuilder jwtBuilder;
 | 
			
		||||
    private final RedisUtils redisUtils;
 | 
			
		||||
    private final SecurityProperties properties;
 | 
			
		||||
    public static final String AUTHORITIES_UUID_KEY = "uuid";
 | 
			
		||||
    public static final String AUTHORITIES_UUID_KEY = "uid";
 | 
			
		||||
    public static final String AUTHORITIES_UID_KEY = "userId";
 | 
			
		||||
 | 
			
		||||
    public TokenProvider(SecurityProperties properties, RedisUtils redisUtils) {
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +78,7 @@ public class TokenProvider implements InitializingBean {
 | 
			
		|||
        // 设置用户ID
 | 
			
		||||
        claims.put(AUTHORITIES_UID_KEY, user.getUser().getId());
 | 
			
		||||
        // 设置UUID,确保每次Token不一样
 | 
			
		||||
        claims.put(AUTHORITIES_UUID_KEY, IdUtil.simpleUUID());
 | 
			
		||||
        claims.put(AUTHORITIES_UUID_KEY, IdUtil.objectId());
 | 
			
		||||
        return jwtBuilder
 | 
			
		||||
                .setClaims(claims)
 | 
			
		||||
                .setSubject(user.getUsername())
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +135,16 @@ public class TokenProvider implements InitializingBean {
 | 
			
		|||
     */
 | 
			
		||||
    public String loginKey(String token) {
 | 
			
		||||
        Claims claims = getClaims(token);
 | 
			
		||||
        String md5Token = DigestUtil.md5Hex(token);
 | 
			
		||||
        return properties.getOnlineKey() + claims.getSubject() + "-" + md5Token;
 | 
			
		||||
        return properties.getOnlineKey() + claims.getSubject() + ":" + getId(token);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 获取登录用户TokenKey
 | 
			
		||||
     * @param token /
 | 
			
		||||
     * @return /
 | 
			
		||||
     */
 | 
			
		||||
    public String getId(String token) {
 | 
			
		||||
        Claims claims = getClaims(token);
 | 
			
		||||
        return claims.get(AUTHORITIES_UUID_KEY).toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -53,11 +53,12 @@ public class OnlineUserService {
 | 
			
		|||
    public void save(JwtUserDto jwtUserDto, String token, HttpServletRequest request){
 | 
			
		||||
        String dept = jwtUserDto.getUser().getDept().getName();
 | 
			
		||||
        String ip = StringUtils.getIp(request);
 | 
			
		||||
        String id = tokenProvider.getId(token);
 | 
			
		||||
        String browser = StringUtils.getBrowser(request);
 | 
			
		||||
        String address = StringUtils.getCityInfo(ip);
 | 
			
		||||
        OnlineUserDto onlineUserDto = null;
 | 
			
		||||
        try {
 | 
			
		||||
            onlineUserDto = new OnlineUserDto(jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date());
 | 
			
		||||
            onlineUserDto = new OnlineUserDto(id, jwtUserDto.getUsername(), jwtUserDto.getUser().getNickName(), dept, browser , ip, address, EncryptUtils.desEncrypt(token), new Date());
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            log.error(e.getMessage(),e);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,9 @@ import java.util.Date;
 | 
			
		|||
@NoArgsConstructor
 | 
			
		||||
public class OnlineUserDto {
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "Token编号")
 | 
			
		||||
    private String uid;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "用户名")
 | 
			
		||||
    private String userName;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,7 +23,7 @@ outagedetectioninterval=2
 | 
			
		|||
filter=true
 | 
			
		||||
 | 
			
		||||
# 过滤 Log 时所排除的 sql 关键字,以逗号分隔
 | 
			
		||||
exclude=select 1
 | 
			
		||||
exclude=SELECT 1,INSERT INTO sys_log
 | 
			
		||||
 | 
			
		||||
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
 | 
			
		||||
excludecategories=info,debug,result,commit,resultset
 | 
			
		||||
		Loading…
	
		Reference in New Issue