package top.mytao.myproject.platform.aspact;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.bouncycastle.asn1.ocsp.ResponseData;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import top.mytao.myproject.business.event.LogEvent;
import top.mytao.myproject.platform.Constants;
import top.mytao.myproject.platform.controller.entity.LogEntity;
import top.mytao.myproject.platform.enums.SysExpEnum;
import top.mytao.myproject.platform.util.IpAddressUtil;
import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
@Slf4j
@Component
@Aspect
public class WebLogAspect {
public static final String GET = "GET";
@Autowired
private ApplicationContext context;
@Pointcut("execution(public * top.mytao.myproject.platform.controller.BaseController+.*(..))")
public void requestServer() {
}
@Around("requestServer()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long startTime = System.currentTimeMillis();
try {
Object result = pjp.proceed();
processSuccess(startTime, pjp, result);
return result;
} catch (Exception e) {
log.error("http request failed!", e);
processError(startTime, pjp, e.getMessage());
throw e;
}
}
private LogEntity buildLogEntity(ProceedingJoinPoint pjp, long startTime, String returnCode) {
ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sra.getRequest();
LogEntity logEntity = new LogEntity();
logEntity.setIp(IpAddressUtil.getIpAdrress(request));
logEntity.setRequestUrl(request.getRequestURI());
logEntity.setLogId(MDC.get(Constants.TRACE_ID));
logEntity.setHttpMethod(request.getMethod());
logEntity.setTargetClass(pjp.getTarget().getClass().getSimpleName());
logEntity.setTargetMethod(pjp.getSignature().getName());
logEntity.setRequestParams(getRequestParams(pjp, request));
logEntity.setStartTime(startTime);
logEntity.setReturnCode(returnCode);
long endTime = System.currentTimeMillis();
logEntity.setCost(endTime - startTime);
logEntity.setEndTime(endTime);
return logEntity;
}
private String getRequestParams(JoinPoint joinPoint, HttpServletRequest request) {
String requestParams;
if (GET.equals(request.getMethod())) {
requestParams = request.getQueryString();
}else {
requestParams = JSONObject.toJSONString(joinPoint.getArgs());
}
return requestParams;
}
private void processError(long startTime, ProceedingJoinPoint pjp, String errorMessage) {
LogEntity logEntity = buildLogEntity(pjp, startTime, SysExpEnum.UNKNOW_ERROR.getCode());
logEntity.setErrorInfo(errorMessage);
pushLog(logEntity);
}
private void processSuccess(long startTime, ProceedingJoinPoint pjp, Object result) {
LogEntity logEntity = buildLogEntity(pjp, startTime, SysExpEnum.SUCCESS.getCode());
String response = getResponse(result);
logEntity.setResponse(response);
pushLog(logEntity);
}
private void pushLog(LogEntity logEntity) {
LogEvent.Builder logEvent = new LogEvent.Builder(this).logEntity(logEntity);
context.publishEvent(logEvent.build());
log.info(JSON.toJSONString(logEntity));
}
private String getResponse(Object result) {
String response = "";
if (Objects.isNull(result)) {
return response;
}
if (result instanceof ResponseData) {
response = JSON.toJSONString(result, SerializerFeature.WriteDateUseDateFormat);
}else {
response = String.valueOf(result);
}
return response;
}
}