package com.geely.dt.configuration;
import cn.evun.sweet.framework.common.util.time.DateUtils;
import cn.evun.sweet.framework.core.mvc.APIResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.geely.dt.core.auth.CurrentUserContext;
import com.geely.dt.log.DataOperationLog;
import com.google.common.collect.Maps;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
/**
* Created by Jiyang.Zheng on 2019/2/27 9:24.
*/
@Slf4j
@Aspect
@Component
public class WebLogAspect {
ThreadLocal<Map<String,Object>> logParam = new ThreadLocal<>();
Map<String,String> clazzMethod = Maps.newConcurrentMap();
@Value("${spring.application.name}")
private String serviceName;
@Pointcut("execution(public * com.geely.dt.controller..*.*(..))")
public void weblog(){}
@Before("weblog()")
public void doBefore(JoinPoint joinPoint) {
//获取请求报文头部元数据
ServletRequestAttributes requestAttributes=(ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
//获取请求对象
HttpServletRequest request=requestAttributes.getRequest();
Map<String,Object> map = Maps.newTreeMap();
map.put("url",request.getRequestURL().toString());
map.put("requestMethod",request.getMethod());
map.put("methodName",getMethodDescription(joinPoint));
map.put("method",joinPoint.getTarget().getClass().getName());
map.put("requestIp", getIPAddress(request));
map.put("userInfo", CurrentUserContext.getSessionUser());
map.put("args", getPram( joinPoint));
map.put("serviceName",serviceName);
map.put("operationTime", DateUtils.formatDateTime(new Date()));
map.put("timestamp",System.currentTimeMillis());
logParam.set(map);
}
@AfterReturning(returning = "ret",pointcut = "weblog()")
public void doAfter(Object ret){
Map<String,Object> map = logParam.get();
if (ret instanceof APIResponse){
APIResponse rsp = (APIResponse) ret;
map.put("response",rsp.getData());
}else {
map.put("response",ret);
}
map.put("spend",(System.currentTimeMillis()-(Long)map.get("timestamp") +"") );
DataOperationLog.log(map);
}
/**
* 指定方法内抛出异常时才会被通知
* 属性 throwing上设置异常类 Throwable将会捕获任何错误和异常, 或按需设置指定异常类
*/
@AfterThrowing(pointcut = "weblog()", throwing="ex")
public void aspect4(JoinPoint joinPoint, Exception ex){
// Map<String,Object> map = logParam.get();
map.put("ex",ex.getMessage() );
map.put("spend",(System.currentTimeMillis()-(Long)map.get("timestamp") +"") );
log.error("AfterThrowing error param: "+ JSONObject.toJSONString(getPram( joinPoint)),ex);
logParam.remove();
DataOperationLog.log(map);
}
protected String getMethodDescription(JoinPoint joinPoint) {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
if (StringUtils.isNotEmpty(clazzMethod.get(targetName+methodName))){
return clazzMethod.get(targetName+methodName);
}
Class<?> targetClass = null;
try {
targetClass = Class.forName(targetName);
} catch (ClassNotFoundException e) {
return "";
}
Api api = targetClass.getAnnotation(Api.class);
Method[] methods = targetClass.getMethods();
String description = "";
if (api != null && api.tags() != null){
description = api.tags()[0] +"-";
}
for (Method method : methods) {
if(method.getName().equals(methodName)) {
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
if (apiOperation != null){
description = description +apiOperation.value();
break;
}
}
}
clazzMethod.put(targetName+methodName,description);
return description;
}
private String getPram(JoinPoint joinPoint){
String[] parameterNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
StringBuilder sb = new StringBuilder();
if (Objects.nonNull(parameterNames)) {
for (int i = 0; i < parameterNames.length; i++) {
String value = joinPoint.getArgs()[i] != null ? joinPoint.getArgs()[i].toString() : "null";
sb.append(parameterNames[i] + ":" + value + "; ");
}
}
return sb.toString();
}
private static String unknown = "unknown";
private static String comma = ",";
public static String getIPAddress(HttpServletRequest request) {
String ipAddress = request.getHeader("HTTP_X_FORWARDED_FOR");
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("X-Forwarded-For");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("X-Real-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || unknown.equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
// 对于通过多个代理的情况,第一个 IP 为客户端真实 IP,多个 IP 按照','分割
// "***.***.***.***".length() = 15
if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(comma) >= 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
return ipAddress;
}
}
|