| package com.xzx.gc.filter;  | 
|   | 
| import cn.hutool.core.collection.CollUtil;  | 
| import cn.hutool.core.convert.Convert;  | 
| import cn.hutool.core.exceptions.ExceptionUtil;  | 
| import cn.hutool.core.lang.Dict;  | 
| import cn.hutool.core.text.StrBuilder;  | 
| import cn.hutool.core.util.ArrayUtil;  | 
| import cn.hutool.core.util.StrUtil;  | 
| import cn.hutool.core.util.URLUtil;  | 
| import cn.hutool.extra.emoji.EmojiUtil;  | 
| import cn.hutool.extra.servlet.ServletUtil;  | 
| import com.xzx.gc.common.constant.CommonEnum;  | 
| import com.xzx.gc.common.constant.MqConstants;  | 
| import com.xzx.gc.common.dto.log.*;  | 
| import com.xzx.gc.common.exception.BusinessException;  | 
| import com.xzx.gc.common.exception.PlatformException;  | 
| import com.xzx.gc.common.exception.RestException;  | 
| import com.xzx.gc.common.utils.*;  | 
| import com.xzx.gc.entity.CoreUser;  | 
| import com.xzx.gc.interceptor.SqlInterceptor;  | 
| import com.xzx.gc.model.MiException;  | 
| import com.xzx.gc.util.SessionUtil;  | 
| import io.swagger.annotations.Api;  | 
| import io.swagger.annotations.ApiOperation;  | 
| import lombok.extern.slf4j.Slf4j;  | 
| import org.apache.ibatis.mapping.SqlCommandType;  | 
| import org.aspectj.lang.JoinPoint;  | 
| import org.aspectj.lang.ProceedingJoinPoint;  | 
| import org.aspectj.lang.Signature;  | 
| import org.aspectj.lang.annotation.*;  | 
| import org.aspectj.lang.reflect.MethodSignature;  | 
| import org.springframework.beans.factory.annotation.Autowired;  | 
| import org.springframework.stereotype.Component;  | 
|   | 
| import javax.servlet.http.HttpServletRequest;  | 
| import java.lang.reflect.Method;  | 
| import java.util.List;  | 
| import java.util.stream.Collectors;  | 
|   | 
|   | 
| /**  | 
|  * 日志切面  | 
|  */  | 
| @Aspect  | 
| @Component  | 
| @Slf4j  | 
| public class LogFilter {  | 
|   | 
|   | 
|     public static  final String AROUND_PARAM="aroundParam";  | 
|   | 
|     //错误异常打印行数  | 
|     public static  final int ERR_LINE=50000;  | 
|     @Autowired  | 
|     private BusinessUtil businessUtil;  | 
|   | 
|     @Autowired  | 
|     private SpringUtil springUtil;  | 
|   | 
|     @Autowired  | 
|     private MqUtil mqUtil;  | 
|   | 
|     /** 以 controller 包下定义的所有请求为切入点 */  | 
|     @Pointcut("execution(public * com.xzx.gc.*.controller..*.*(..))")  | 
|     public void webLog() {}  | 
|   | 
|     /**  | 
|      * 在切点之前织入  | 
|      * @param joinPoint  | 
|      * @throws Throwable  | 
|      */  | 
|     @Before("webLog()")  | 
|     public void doBefore(JoinPoint joinPoint) throws Throwable {  | 
|   | 
|     }  | 
|   | 
|     /**  | 
|      * 在切点之后织入  | 
|      * @throws Throwable  | 
|      */  | 
|     @After("webLog()")  | 
|     public void doAfter() throws Throwable {  | 
|     }  | 
|   | 
|     /**  | 
|      * 环绕  | 
|      * @param joinPoint  | 
|      * @return  | 
|      * @throws Throwable  | 
|      */  | 
|     @Around("webLog()")  | 
|     public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {  | 
|         HttpServletRequest request = springUtil.getCurrentRequest();  | 
|         Dict dict = get(joinPoint,request);  | 
|         request.setAttribute(AROUND_PARAM,dict);  | 
|         // 开始打印请求日志  | 
|         String userId = request.getHeader("userId");  | 
|         if(StringUtils.isNotBlank(userId)){  | 
|             String ip = IpUtils.getIpAddr(request);  | 
|             businessUtil.saveLoginInfoToRedis(ip,userId);  | 
|         }  | 
|         Object result = joinPoint.proceed();  | 
|         String resultJson = businessUtil.prettyOut(result);  | 
|   | 
|         //返回结果处理  | 
|         List<SqlDto> sqlList = (List<SqlDto>) request.getAttribute(SqlInterceptor.SQL_PARAM);  | 
|         // 执行耗时  | 
|         Long startTime = dict.getLong("startTime");  | 
|         long l = System.currentTimeMillis() - startTime;  | 
|   | 
|   | 
|         IntefaceAdminLog intefaceAdminLog = (IntefaceAdminLog) dict.get("inteface");  | 
|         intefaceAdminLog.setRunTime(Convert.toStr(l));  | 
|         intefaceAdminLog.setLogLevel(CommonEnum.调试级别.getValue());  | 
|         intefaceAdminLog.setOutParameter(EmojiUtil.removeAllEmojis(resultJson));  | 
|   | 
|         if(CollUtil.isNotEmpty(sqlList)){  | 
|             String sql=sqlList.stream().map(x->x.getSql()).collect(Collectors.joining(";"));  | 
|             intefaceAdminLog.setSqlParameter(sql);  | 
|         }  | 
|   | 
|         //不是后台请求才发送info日志队列  | 
|   | 
|   | 
| //        if(SpringUtil.isTest()||SpringUtil.isCheck()||SpringUtil.isDev()){  | 
| //            mqUtil.send(MqConstants.INTEFACE_ADMIN_LOG_QUEUE, intefaceAdminLog);  | 
| //        }else {  | 
| //            if (!dict.getBool("isAdmin")) {  | 
| //                mqUtil.send(MqConstants.INTEFACE_ADMIN_LOG_QUEUE, intefaceAdminLog);  | 
| ////            OperationAppLog operationAppLog = (OperationAppLog) dict.get("operation");  | 
| ////            mqUtil.send(MqConstants.OPERATION_APP_LOG_QUEUE, operationAppLog);  | 
| //            }  | 
| //        }  | 
|         mqUtil.send(MqConstants.INTEFACE_ADMIN_LOG_QUEUE, intefaceAdminLog);  | 
|         out(dict,sqlList,resultJson,l+"",CommonEnum.调试级别.getValue());  | 
|         clear(request);  | 
|         return result;  | 
|     }  | 
|   | 
|   | 
|     /**  | 
|      *  | 
|      * afterThrowable:(统一异常处理). <br/>  | 
|      *  | 
|      * @author fenglanglang  | 
|      * @param e  | 
|      */  | 
|     @AfterThrowing(pointcut="webLog()",throwing="e")  | 
|     public void afterThrowable(Throwable e) {  | 
|         HttpServletRequest request = springUtil.getCurrentRequest();  | 
|         if (request != null) {  | 
|             List<SqlDto> sqlList = (List<SqlDto>) request.getAttribute(SqlInterceptor.SQL_PARAM);  | 
|             Dict dict = (Dict) request.getAttribute(AROUND_PARAM);  | 
|             String l = null;  | 
|             if (dict != null) {  | 
|                 Long startTime = dict.getLong("startTime");  | 
|                 l = Convert.toStr(System.currentTimeMillis() - startTime);  | 
|                 IntefaceAdminLog intefaceAdminLog = (IntefaceAdminLog) dict.get("inteface");  | 
|                 intefaceAdminLog.setRunTime(Convert.toStr(l));  | 
|                 String errMsg=null;  | 
|                 String logLevel=CommonEnum.调试级别.getValue();  | 
|                 if(e instanceof BusinessException){  | 
|                     errMsg=((BusinessException) e).getDebugMsg();  | 
|                     intefaceAdminLog.setLogLevel(CommonEnum.调试级别.getValue());  | 
|                     intefaceAdminLog.setOutParameter(errMsg);  | 
|                 }else if(e instanceof RestException){  | 
|                     errMsg=((RestException) e).getMsg();  | 
|                     intefaceAdminLog.setLogLevel(CommonEnum.调试级别.getValue());  | 
|                     intefaceAdminLog.setOutParameter(errMsg);  | 
|                 }else if(e instanceof MiException){  | 
|                     errMsg= e.getMessage();  | 
|                     intefaceAdminLog.setLogLevel(CommonEnum.调试级别.getValue());  | 
|                     intefaceAdminLog.setOutParameter(errMsg);  | 
|                 }else {  | 
|                     if(SpringUtil.isDevOrTestOrCheck()){  | 
|                         errMsg = ExceptionUtil.stacktraceToString(e, ERR_LINE);  | 
|                     }else{  | 
|                         errMsg = ExceptionUtil.stacktraceToOneLineString(e, ERR_LINE);  | 
|                     }  | 
|                     intefaceAdminLog.setErrMessage(errMsg);  | 
|                     intefaceAdminLog.setLogLevel(CommonEnum.错误级别.getValue());  | 
|                     logLevel=CommonEnum.错误级别.getValue();  | 
|                 }  | 
|                 if (CollUtil.isNotEmpty(sqlList)) {  | 
|                     String sql = sqlList.stream().map(x -> x.getSql()).collect(Collectors.joining(";"));  | 
|                     intefaceAdminLog.setSqlParameter(sql);  | 
|                 }  | 
|                 mqUtil.send(MqConstants.INTEFACE_ADMIN_LOG_QUEUE, intefaceAdminLog);  | 
| //                if(!dict.getBool("isAdmin")){  | 
| //                    OperationAppLog operationAppLog = (OperationAppLog) dict.get("operation");  | 
| //                    mqUtil.send(MqConstants.OPERATION_APP_LOG_QUEUE, operationAppLog);  | 
| //                }  | 
|                 out(dict, sqlList, errMsg, l, logLevel);  | 
|             }  | 
|             clear(request);  | 
|         }  | 
|     }  | 
|   | 
|   | 
|     /**  | 
|      * 组装  | 
|      * @param joinPoint  | 
|      * @return  | 
|      * @throws NoSuchMethodException  | 
|      */  | 
|     private Dict get(JoinPoint joinPoint,HttpServletRequest request) throws NoSuchMethodException {  | 
|         long startTime=System.currentTimeMillis();  | 
|         Dict dict=Dict.create();  | 
|         // 开始打印请求日志  | 
|         String clientType = request.getHeader("clientType");  | 
|         clientType=businessUtil.getClientTypeName(clientType);  | 
|   | 
|         //接口描述  | 
|         String desc="";  | 
|         //接口所在模块  | 
|         String module="";  | 
|         Signature signature = joinPoint.getSignature();  | 
|         String methodName = signature.getName();  | 
|         //类  | 
|         Class declaringType = signature.getDeclaringType();  | 
|         String className = declaringType.getName();  | 
|         Class[] parameterTypes = ((MethodSignature)signature).getMethod().getParameterTypes();  | 
|         //方法  | 
|         Method method = declaringType.getMethod(signature.getName(),parameterTypes);  | 
|   | 
|         if (method.isAnnotationPresent(ApiOperation.class)) {  | 
|             ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);  | 
|             desc=apiOperation.value();  | 
|         }  | 
|   | 
| //        if (declaringType.isAnnotationPresent(Api.class)) {  | 
| //            Api api = (Api) declaringType.getAnnotation(Api.class);  | 
| //            String[] tags = api.tags();  | 
| //            if(ArrayUtil.isNotEmpty(tags)){  | 
| //                module=tags[0];  | 
| //            }else {  | 
| //                module=desc;  | 
| //            }  | 
| //        }  | 
|   | 
|         String inParam = businessUtil.prettyInParam(joinPoint.getArgs());  | 
|         String codePath=className+"."+methodName;  | 
|   | 
|         boolean isAdmin = businessUtil.isAdmin(request.getRequestURI());  | 
|   | 
|         String userId;  | 
|         if(isAdmin){  | 
|             CoreUser user= (CoreUser) request.getSession().getAttribute(SessionUtil.ACCESS_CURRENT_USER);  | 
|             userId=user!=null?user.getId().toString():"匿名";  | 
|         }else {  | 
|             userId = request.getHeader("userId");  | 
|             userId = StrUtil.isBlank(userId) ? "匿名" : userId;  | 
|         }  | 
|   | 
|         String platName= isAdmin ?"后台接口":"前台接口";  | 
|   | 
|   | 
|         ConsoleDto in = in(request, desc, codePath, clientType,platName,inParam);  | 
|         dict.put("console",in);  | 
|   | 
|   | 
|         IntefaceAdminLog intefaceAdminLog =new IntefaceAdminLog();  | 
|         intefaceAdminLog.setMethodPath(request.getRequestURI());  | 
|         intefaceAdminLog.setMethodDesc(desc);  | 
|         intefaceAdminLog.setMethodName(className+"."+methodName);  | 
|         intefaceAdminLog.setIntoParameter(EmojiUtil.removeAllEmojis(inParam));  | 
|         intefaceAdminLog.setImplementType(isAdmin ?"2":"1");  | 
|         intefaceAdminLog.setUserId(userId);  | 
|   | 
|         dict.put("inteface", intefaceAdminLog);  | 
|   | 
|   | 
| //        if(!isAdmin) {  | 
| //            OperationAppLog operationAppLog = new OperationAppLog();  | 
| //            operationAppLog.setOpreateName(userId);  | 
| //            if ("WEB".equals(clientType)) {  | 
| //                operationAppLog.setAppPrograme("1");  | 
| //            } else {  | 
| //                operationAppLog.setAppPrograme("2");  | 
| //            }  | 
| //            operationAppLog.setMethodName(module);  | 
| //            operationAppLog.setOperateAction(null);  | 
| //            dict.put("operation",operationAppLog);  | 
| //        }  | 
|   | 
|   | 
|         dict.put("startTime",startTime);  | 
|   | 
|         dict.put("isAdmin",isAdmin);  | 
|         return dict;  | 
|     }  | 
|   | 
|     /**  | 
|      * 清除  | 
|      * @param request  | 
|      */  | 
|     private void clear(HttpServletRequest request){  | 
|         request.removeAttribute(AROUND_PARAM);  | 
|         request.removeAttribute(SqlInterceptor.SQL_PARAM);  | 
|     }  | 
|   | 
|     /**  | 
|      * 请求  | 
|      * @param request  | 
|      * @param desc  | 
|      * @param codePath  | 
|      * @param inParam  | 
|      * @return  | 
|      */  | 
|     private ConsoleDto in(HttpServletRequest request,String desc,String codePath,String clientType, String platName,String inParam){  | 
|         ConsoleDto consoleDto=new ConsoleDto();  | 
|   | 
|         consoleDto.setTitle(businessUtil.checkProject(request.getRequestURI()));  | 
|         List<ConsoleContentDto> list=CollUtil.newArrayList();  | 
|         ConsoleContentDto consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求地址");  | 
|         consoleContentDto.setValue(URLUtil.normalize(request.getRequestURL().toString()));  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求描述");  | 
|         consoleContentDto.setValue(desc);  | 
|         list.add(consoleContentDto);  | 
|   | 
| //        consoleContentDto=new ConsoleContentDto();  | 
| //        consoleContentDto.setName("请求方法");  | 
| //        consoleContentDto.setValue(request.getMethod());  | 
| //        list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求接口");  | 
|         consoleContentDto.setValue(codePath);  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求I P ");  | 
|         consoleContentDto.setValue(IpUtils.getIpAddr(request));  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求平台");  | 
|         consoleContentDto.setValue(platName);  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求来源");  | 
|         consoleContentDto.setValue(clientType);  | 
|         list.add(consoleContentDto);  | 
|   | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求头部");  | 
|         consoleContentDto.setValue(businessUtil.prettyHeader(ServletUtil.getHeaderMap(request)));  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleContentDto=new ConsoleContentDto();  | 
|         consoleContentDto.setName("请求入参");  | 
|         consoleContentDto.setValue(inParam);  | 
|         list.add(consoleContentDto);  | 
|   | 
|         consoleDto.setList(list);  | 
|   | 
|         return consoleDto;  | 
|     }  | 
|   | 
|     /**  | 
|      * 输出  | 
|      * @param dict  | 
|      * @param sqlList  | 
|      * @param resultJson  | 
|      * @param l  | 
|      */  | 
|     private void out(Dict dict, List<SqlDto> sqlList,String resultJson,String l,String type){  | 
|         ConsoleDto consoleDto= (ConsoleDto) dict.get("console");  | 
|         consoleDto.setHeader("您有新的请求");  | 
|         consoleDto.setEmjio("fish");  | 
|         List<ConsoleContentDto> list = consoleDto.getList();  | 
|   | 
|         if(StrUtil.isNotBlank(resultJson)) {  | 
|             ConsoleContentDto consoleContentDto = new ConsoleContentDto();  | 
|             if(CommonEnum.调试级别.getValue().equals(type)) {  | 
|                 consoleContentDto.setName("响应出参");  | 
|             }else if(CommonEnum.错误级别.getValue().equals(type)){  | 
|                 consoleContentDto.setName("异常信息");  | 
|             }  | 
|             consoleContentDto.setValue(resultJson);  | 
|             list.add(consoleContentDto);  | 
|         }  | 
|   | 
|         if(CollUtil.isNotEmpty(sqlList)) {  | 
| //            String sql=sqlList.stream().map(x->x.getSql()).collect(Collectors.joining(";\n                "));  | 
| //            long effectNum=sqlList.stream().mapToLong(x->Convert.toLong(x.getEffectNum())).sum();  | 
|             StrBuilder strBuilder = StrBuilder.create();  | 
|             for (int i = 0; i < sqlList.size(); i++) {  | 
|                 SqlDto sqlDto = sqlList.get(i);  | 
|                 strBuilder.append(sqlDto.getSql());  | 
|                 strBuilder.append(";\n               ");  | 
|                 if(SqlCommandType.SELECT.name().equals(sqlDto.getSqlType())){  | 
|                     strBuilder.append("【返回结果数:"+sqlDto.getEffectNum()+"】");  | 
|                 }else {  | 
|                     strBuilder.append("【影响的行数:"+sqlDto.getEffectNum()+"】");  | 
|                 }  | 
|   | 
|                 if(i!=sqlList.size()-1) {  | 
|                     strBuilder.append("\n               ");  | 
|                 }  | 
|             }  | 
|             long costTime=sqlList.stream().mapToLong(x->Convert.toLong(x.getCostTime())).sum();  | 
|             ConsoleContentDto consoleContentDto = new ConsoleContentDto();  | 
|             consoleContentDto.setName("执行SQL ");  | 
|             consoleContentDto.setValue(strBuilder.toString());  | 
|             list.add(consoleContentDto);  | 
|   | 
|             consoleContentDto=new ConsoleContentDto();  | 
|             consoleContentDto.setName("SQL耗时 ");  | 
|             consoleContentDto.setValue(costTime+"毫秒");  | 
|             list.add(consoleContentDto);  | 
|   | 
| //            consoleContentDto=new ConsoleContentDto();  | 
| //            consoleContentDto.setName("影响行数");  | 
| //            consoleContentDto.setValue(effectNum+"");  | 
| //            list.add(consoleContentDto);  | 
|         }  | 
|   | 
|   | 
|         if(StrUtil.isNotBlank(l)) {  | 
|             ConsoleContentDto consoleContentDto = new ConsoleContentDto();  | 
|             consoleContentDto.setName("请求耗时");  | 
|             consoleContentDto.setValue(l + "毫秒");  | 
|             list.add(consoleContentDto);  | 
|         }  | 
|   | 
|         ConsoleContentDto consoleContentDtoType = new ConsoleContentDto();  | 
|         consoleContentDtoType.setName("请求状态");  | 
|         if(CommonEnum.调试级别.getValue().equals(type)) {  | 
|             consoleContentDtoType.setValue("大吉大利今晚吃鸡!");  | 
|         }else if(CommonEnum.错误级别.getValue().equals(type)){  | 
|             consoleContentDtoType.setValue("又失败了我太难了!");  | 
|         }  | 
|         list.add(consoleContentDtoType);  | 
|   | 
|         String console = businessUtil.console(consoleDto);  | 
|         log.debug(console);  | 
|   | 
|     }  | 
|   | 
|   | 
|   | 
| }  | 
|   |