aop切面记日志
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切面记日志的更多相关文章
- 使用aop切面编写日志模块
我们先自定义一个注解(一个有关自定义注解的LJ文章 https://www.cnblogs.com/guomie/p/10824973.html) /** * * 自定义日志注解 * Retentio ...
- Logstash+ Kafka基于AOP 实时同步日志到es
Logstash是一个开源数据收集引擎,具有实时管道功能.Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地,logstash丰富的插件(logstash-in ...
- 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- Spring MVC通过AOP切面编程 来拦截controller 实现日志的写入
首选需要参考的是:[参考]http://www.cnblogs.com/guokai870510826/p/5977948.html http://www.cnblogs.com/guokai8 ...
- Spring Boot 2.0 教程 | AOP 切面统一打印请求日志
欢迎关注微信公众号: 小哈学Java 文章首发于个人网站 https://www.exception.site/springboot/spring-boot-aop-web-request 本节中,您 ...
- Springboot项目使用aop切面保存详细日志到ELK日志平台
上一篇讲过了将Springboot项目中logback日志插入到ELK日志平台,它只是个示例.这一篇来看一下实际使用中,我们应该怎样通过aop切面,拦截所有请求日志插入到ELK日志系统.同时,由于往往 ...
- SpringBoot2.0 基础案例(11):配置AOP切面编程,解决日志记录业务
本文源码 GitHub地址:知了一笑 https://github.com/cicadasmile/spring-boot-base 一.AOP切面编程 1.什么是AOP编程 在软件业,AOP为Asp ...
- Spring Boot 自定义注解,AOP 切面统一打印出入参请求日志
其实,小哈在之前就出过一篇关于如何使用 AOP 切面统一打印请求日志的文章,那为什么还要再出一篇呢?没东西写了? 哈哈,当然不是!原因是当时的实现方案还是存在缺陷的,原因如下: 不够灵活,由于是以所有 ...
- Spring Boot 中使用自定义注解,AOP 切面打印出入参日志及Dubbo链路追踪透传traceId
一.使用背景 开发排查系统问题用得最多的手段就是查看系统日志,在分布式环境中一般使用 ELK 来统一收集日志,但是在并发大时使用日志定位问题还是比较麻烦,由于大量的其他用户/其他线程的日志也一起输出穿 ...
- 十:SpringBoot-配置AOP切面编程,解决日志记录业务
SpringBoot-配置AOP切面编程,解决日志记录业务 1.AOP切面编程 1.1 AOP编程特点 1.2 AOP中术语和图解 2.SpringBoot整合AOP 2.1 核心依赖 2.2 编写日 ...
随机推荐
- day06-功能实现05
家居网购项目实现05 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 12.功能11-后台分页(分页显示家居) 12.1需求分析 ...
- 多线程爬取wallhaven
前言 最近整理自己的项目时,发现之前自己写的爬取wallhaven网站顿时有来的兴趣决定再写一遍来回顾自己以前学的知识 网站地址:"https://wallhaven.cc/" 1 ...
- [OpenCV实战]24 使用OpenCV进行曝光融合
目录 1 什么是曝光融合 2 曝光融合的原理 3 代码与结果 4 参考 本教程中,我们将了解使用OpenCV的Exposure Fusion(曝光融合). 1 什么是曝光融合 曝光融合是一种将使用不同 ...
- HBase详解(02) - HBase-2.0.5安装
HBase详解(02) - HBase-2.0.5安装 HBase安装环境准备 Zookeeper安装 Zookeeper安装参考<Zookeeper详解(02) - zookeeper安装部署 ...
- C++ 编译依赖管理系统分析以及 srcdep 介绍
C++ 编译依赖管理系统分析以及 srcdep 介绍 如果用 C++ 写一个中小型软件,有要用到很多第三方库的话,相信不少人会觉得比较麻烦.很多新兴的语言都有了统一的依赖管理系统和构建系统,但是 C/ ...
- 刷题笔记——1112:C语言考试练习题_一元二次方程
题目 1112:C语言考试练习题_一元二次方程 代码 import math while True: try: a,b,c=map(float,input().strip().split()) del ...
- 精华推荐 | 【JVM深层系列】「GC底层调优系列」一文带你彻底加强夯实底层原理之GC垃圾回收技术的分析指南(GC原理透析)
前提介绍 很多小伙伴,都跟我反馈,说自己总是对JVM这一块的学习和认识不够扎实也不够成熟,因为JVM的一些特性以及运作机制总是混淆以及不确定,导致面试和工作实战中出现了很多的纰漏和短板,解决广大小伙伴 ...
- NG-Alain + Angular11使用ModalHelper实现简单版本弹框,代码超级少,记得模块要引用这个组件
先看一下目录结构 --aa-item ----modal-compment ------modal-compment.component.html ------modal-compment.compo ...
- 创建型模式 - 单例模式Singleton
单例模式的定义与特点 创建型模式: 单例模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式. 例如,Windows中只能打开一个任务管理器,这样可以避免因打开多个任务 ...
- 前端基础知识-css(一)个人学习记录
待补充 flex及其属性 https://blog.csdn.net/weixin_44706267/article/details/121291934 css3新特性 sass和less https ...