package com.netauth.utils.component;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface LogAnnotation {
}

  

package com.infosec.config;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.StringUtils;
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.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import com.alibaba.fastjson.JSONObject;
import com.infosec.user.compoent.UserInternationKeyConst;
import com.netauth.api.logcollection.Log;
import com.netauth.utils.Const;
import com.netauth.utils.GetMacAddress;
import com.netauth.utils.LogConst;
import com.netauth.utils.component.LocaleMessageSourceService;
import com.netauth.utils.component.LogAnnotation;
import com.netauth.utils.currentuser.LoginUserUtil;
import com.netauth.utils.gateway.GatewayConst;
import com.netauth.utils.jsonresult.JsonErrotCode;
import com.netauth.utils.jsonresult.JsonResult; import io.swagger.annotations.ApiOperation; @Aspect
@Configuration
public class LogAspect { @Resource
private LocaleMessageSourceService localeMessageSourceService; @Autowired
private Log log; public LogAspect() {
} @Pointcut("@within(com.netauth.utils.component.LogAnnotation) || @annotation(com.netauth.utils.component.LogAnnotation)")
public void pointCutMethod() {
} // 声明环绕通知
@Around("pointCutMethod()")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
Long startTime = System.currentTimeMillis();
// 获取request对象
RequestAttributes ra = RequestContextHolder.getRequestAttributes();
ServletRequestAttributes sra = (ServletRequestAttributes) ra;
Object ret = null;
if(sra == null) {
ret = pjp.proceed();
return ret;
} HttpServletRequest request = sra.getRequest();
String requestURI = request.getServletPath();
Map<String, Object> localUser = LoginUserUtil.getLoginUser(request);
boolean exceptionFlag = false;
Exception exportEx = null;
try {
ret = pjp.proceed();
} catch (Exception e) {
if(requestURI != null && requestURI.indexOf("/export/") != -1) {
exceptionFlag = true;
exportEx = e;
}else {
throw e;
}
} Long endTime = System.currentTimeMillis();
//设置请求路径
if(StringUtils.isEmpty(requestURI) || requestURI.contains(GatewayConst.CLIENT_NO_FILTER)) {
//
}else {
addLog(request,requestURI,exceptionFlag,localUser,pjp,endTime-startTime,ret);
}
if(exceptionFlag) {
throw exportEx;
}
return ret;
} //获取参数名和参数值
public Map<String, Object> getParam(ProceedingJoinPoint proceedingJoinPoint) {
Map<String, Object> map = new HashMap<String, Object>();
Object[] values = proceedingJoinPoint.getArgs();
String[] names = ((MethodSignature) proceedingJoinPoint.getSignature()).getParameterNames();
for (int i = 0; i < names.length; i++) {
map.put(names[i], values[i]);
}
return map;
} private void addLog(HttpServletRequest request,String requestURI,boolean exceptionFlag,Map<String, Object> localUser,ProceedingJoinPoint pjp,Long time,Object ret) throws IOException {
String apiName;
String logType;
MethodSignature signature = (MethodSignature) pjp.getSignature();
Method method = signature.getMethod();
ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
apiName = Objects.nonNull(apiOperation) ? apiOperation.value() : "";
LogAnnotation annotation = method.getAnnotation(LogAnnotation.class);
if(annotation == null) {
annotation = pjp.getTarget().getClass().getAnnotation(LogAnnotation.class);
}
logType = annotation.logtype(); String msg = "";
String code = "";
String model = "";
String appName = "";
String operation = "";
int logLevel = Log.LOG_LEVEL_WARN;
int result = Log.RESULT_FAIULE;
String[] split = requestURI.split("/");
appName = !StringUtils.isEmpty(split[1])? split[1] : appName;
model = !StringUtils.isEmpty(split[2])? split[2] : model;
operation = !StringUtils.isEmpty(split[3])? split[3] : operation; JsonResult res = null;
if(ret!= null && ret instanceof JsonResult) {
res = (JsonResult) ret ;
code = res.getCode();
msg = res.getMsg();
} //没有响应 且操作类型为导出
if(ret == null && "export".equals(operation)) {
//根据是否异常来设置code和msg
if(exceptionFlag) {
code = JsonErrotCode.FAIL_CODE;
}else {
code = JsonErrotCode.SUCCESS_CODE;
}
} String localUserLoginName = "";
String localUserName = "";
String localUserRoles = "";
String localUserDn = "";
String userClientIp = ""; //根据响应code首字母判断成功失败
if(code.startsWith("I")) {
logLevel = Log.LOG_LEVEL_INFO;
result = Log.RESULT_SUCCESS;
if(StringUtils.isEmpty(msg)) {
msg = apiName + "成功";
}
} else if(code.startsWith("W")) {
logLevel = Log.LOG_LEVEL_WARN;
result = Log.RESULT_FAIULE;
if(StringUtils.isEmpty(msg)) {
msg = apiName + "失败";
}
} else if(code.startsWith("E")) {
logLevel = Log.LOG_LEVEL_ERROR;
result = Log.RESULT_FAIULE;
msg = apiName+" 异常 " + (StringUtils.isEmpty(msg) ? "" : msg);
if(res != null) {
res.setMsg(localeMessageSourceService.getMessage(UserInternationKeyConst.SYS_EXCEPTION));
}
} switch (operation) {
case "get":
operation = Log.HOWS_READ; break;
case "update":
operation = Log.HOWS_MODIFY; break;
case "del":
operation = Log.HOWS_DEL; break;
case "add":
operation = Log.HOWS_ADD; break;
case "login":
operation = Log.HOWS_LOGIN; break;
case "export":
operation = Log.HOWS_EXPORT; break;
case "import":
operation = Log.HOWS_IMPORT; break;
case "download":
operation = Log.HOWS_DOWNLOAD; break;
default:
operation = Log.HOWS_OTHERS; break;
} //没有登录调用接口(对外API,注册)
if (localUser == null) { if( LogConst.LOGTYPE_API.equals(appName) ) {
//对外API
String header = request.getHeader(Const.APPID);
localUserLoginName = header;
localUserName = header;
appName = header;
model = LogConst.LOGTYPE_API;
} else if(LogConst.MODEL_FLAG_PORTAL.equals(logType) ) {
if(LogConst.MODEL_FLAG_USER.equals(appName)) {
model = Const.MODEL_USER;
} else if(LogConst.MODEL_FLAG_SMS.equals(appName)) {
model = Const.MODEL_SMS;
} else if(LogConst.MODEL_FLAG_APPROVAL.equals(appName)) {
model = Const.MODEL_APPROVAL;
} else if(LogConst.MODEL_FLAG_PORTALMANAGER.equals(appName)) {
model = Const.MODEL_PORTAL;
}
if(requestURI.indexOf("/get/") != -1) {
operation = Log.HOWS_READ;
}else if (requestURI.indexOf("/update/") != -1) {
operation = Log.HOWS_MODIFY;
}
localUserRoles = "commonuser";
//普通用户调用日志 没有登录时取参数内的登录名做日志参数
String paramKey = annotation.paramKey();
Map<String, Object> param = getParam(pjp);
localUserLoginName = (String) param.get(paramKey);
localUserName = localUserLoginName;
localUserDn = localUserLoginName;
}
userClientIp = GetMacAddress.getIpAddr(request);
}else {
localUserLoginName = (String) localUser.get(LoginUserUtil.USER_LOGINNAME);
localUserName = (String) localUser.get(LoginUserUtil.USER_USERNAME);
localUserRoles = (String) localUser.get(LoginUserUtil.USER_SYSADMIN);
localUserDn = (String) localUser.get(LoginUserUtil.USER_DEPTDN);
userClientIp = (String) localUser.get(LoginUserUtil.USER_CLIENTIP);
}
JSONObject json = new JSONObject();
json.put("logLevel", logLevel);
json.put("model", model);
json.put("localUserLoginName", localUserLoginName);
json.put("userClientIp", userClientIp);
json.put("operation", operation);
json.put("result", result);
json.put("msg", msg);
json.put("localUserName", localUserName);
json.put("localUserRoles", localUserRoles);
json.put("localUserDn", localUserDn);
json.put("appName", appName);
json.put("requestURI", requestURI);
log.writeLog(this.getClass().getName(), logLevel, model, localUserLoginName, userClientIp,
operation, result, msg, localUserName, localUserRoles, localUserDn,
appName,requestURI);//此处就是调用后面保存日志逻辑
}
}

  

aop切面记日志的更多相关文章

  1. 使用aop切面编写日志模块

    我们先自定义一个注解(一个有关自定义注解的LJ文章 https://www.cnblogs.com/guomie/p/10824973.html) /** * * 自定义日志注解 * Retentio ...

  2. Logstash+ Kafka基于AOP 实时同步日志到es

    Logstash是一个开源数据收集引擎,具有实时管道功能.Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地,logstash丰富的插件(logstash-in ...

  3. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  4. Spring MVC通过AOP切面编程 来拦截controller 实现日志的写入

    首选需要参考的是:[参考]http://www.cnblogs.com/guokai870510826/p/5977948.html    http://www.cnblogs.com/guokai8 ...

  5. Spring Boot 2.0 教程 | AOP 切面统一打印请求日志

    欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...

  6. Springboot项目使用aop切面保存详细日志到ELK日志平台

    上一篇讲过了将Springboot项目中logback日志插入到ELK日志平台,它只是个示例.这一篇来看一下实际使用中,我们应该怎样通过aop切面,拦截所有请求日志插入到ELK日志系统.同时,由于往往 ...

  7. SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务

    本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...

  8. Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志

    其实,小哈在之前就出过一篇关于如何使用 AOP 切面统一打印请求日志的文章,那为什么还要再出一篇呢?没东西写了? 哈哈,当然不是!原因是当时的实现方案还是存在缺陷的,原因如下: 不够灵活,由于是以所有 ...

  9. Spring Boot 中使用自定义注解,AOP 切面打印出入参日志及Dubbo链路追踪透传traceId

    一.使用背景 开发排查系统问题用得最多的手段就是查看系统日志,在分布式环境中一般使用 ELK 来统一收集日志,但是在并发大时使用日志定位问题还是比较麻烦,由于大量的其他用户/其他线程的日志也一起输出穿 ...

  10. 十:SpringBoot-配置AOP切面编程,解决日志记录业务

    SpringBoot-配置AOP切面编程,解决日志记录业务 1.AOP切面编程 1.1 AOP编程特点 1.2 AOP中术语和图解 2.SpringBoot整合AOP 2.1 核心依赖 2.2 编写日 ...

随机推荐

  1. 分布式注册服务中心etcd在云原生引擎中的实践

    作者:王雷 etcd是什么 etcd是云原生架构中重要的基础组件,由CNCF孵化托管.ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统,是CoreOS公司发起的一个开源项目,授权协议为A ...

  2. 终于弄明白了 RocketMQ 的存储模型

    RocketMQ 优异的性能表现,必然绕不开其优秀的存储模型 . 这篇文章,笔者按照自己的理解 , 尝试分析 RocketMQ 的存储模型,希望对大家有所启发. 1 整体概览 首先温习下 Rocket ...

  3. [OpenCV实战]6 基于特征点匹配的视频稳像

    目录 1 介绍 1.1 视频稳定的方法 1.2 使用点特征匹配的视频稳定 2 算法 2.1 帧间运动信息获取 2.1.1 合适的特征点获取 2.1.2 Lucas-Kanade光流法 2.1.3 运动 ...

  4. elasticsearch之单请求多查询

    一.需要解决的问题 有的时候我们需要同时执行多个查询,并且需要得到每个单独查询的搜索结果,elasticsearch提供了multi search此需求的支持: 二.elasticsearch mul ...

  5. 孤独的照片【USACO 2021 December Contest Bronze】

    孤独的照片 Farmer John 最近购入了 \(N\) 头新的奶牛,每头奶牛的品种是更赛牛(Guernsey)或荷斯坦牛(Holstein)之一. 奶牛目前排成一排,Farmer John 想要为 ...

  6. P1605迷宫——题解

    展开 题目背景 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫中移动有上下左右四种方式,每次 ...

  7. 基础分类算法_KNN算法

    KNN(K-NearestNeighbor)算法 KNN算法是有监督学习中的分类算法. KNN算法很特殊,可以被认为是没有模型的算法,也可以认为其训练数据集就是模型本身. KNN算法的原理 KNN的原 ...

  8. Python解释器下载与安装

    Python解释器下载与安装 一.Python解释器 1.Python的发展方向 web方向,自动化运维,自动化测试,自动化办公,网络爬虫,金融量化,人工智能,机器学习,数据分析 2.Python解释 ...

  9. qt获取子控件坐标

    QPoint pos = ui->m_blt->mapToGlobal(QPoint(0, 0)); 就可以了.

  10. C#Autofac依赖注入批量注入 (目前版本.netcore3.0)

    上一文:C#依赖注入一看就会系列 链接:C#依赖注入(直白明了)讲解 一看就会系列 - 22222220 - 博客园 (cnblogs.com) 上一次我们知道了 为什么要依赖注入,这次我们就用使用人 ...