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 编写日 ...
随机推荐
- WCF 服务容器化的一些问题
背景 目前项目当中存有 .NET Framework 和 .NET Core 两种类型的项目,但是都需要进行容器化将其分别部署在 Windows 集群和 Linux 集群当中.在 WCF 进行容器化的 ...
- cmd窗口中java命令报错。错误:找不到或无法加载主类 java的jdk安装过程中踩过的坑
错误: 找不到或无法加载主类 HelloWorld 遇到这个问题时,我尝试过网上其他人的做法.有试过添加classpath,也有试过删除classpath.但是依然报错,这里javac可以编译通过,说 ...
- [OpenCV实战]41 嵌入式计算机视觉设备选择
文章目录 1 简介 1.1 深度学习与传统计算机视觉 1.2 性能考量 1.3 社区支持 2 结论 3 参考 在计算机视觉领域中,不同的场景不同的应用程序需要不同的解决方案.在本文中,我们将快速回顾可 ...
- python之路 57 linux 基础 命令与执行效果
虚拟环境的安装与配置 1.VMware软件安装 这里有一个15版本和一个16版本的 链接:https://pan.baidu.com/s/1vkNxxQ6NS9q7XYJ6qiVMaQ 提取码:t3l ...
- 写一个 Markdown 博客客户端
这个"伪需求"是最近才想到的. 关于文章管理的想法,说来话长.我最初是在 CSDN 写技术文章,就用网页上的编辑器.后来在 CppBlog 写,用上了 Windows Live W ...
- iOS14新特性
6月23日凌晨,苹果首次在线上举办全球开发者大会WWDC2020.在大会上,苹果对iOS.iPadOS.macOS.watchOS.tvOS进行更新,其中大家最关心的iOS14,主要更新了36个功能. ...
- 超详细解锁Webpack步骤,踩坑记录
webpack 核心 entry: 入口 output: 输出 loader: 模块转换器,用于把模块原内容按照需求转换成新内容 插件(plugins): 扩展插件,在webpack构建流程中的特定时 ...
- Linux之ssh远程连接
Linux之ssh远程连接 一.下载远程连接工具Xshell Xshell是一种远程连接工具,可用来远程连接虚拟机. Xshell免费版下载地址 输入名字和邮箱,可以在邮箱看到下载Xshell的链接. ...
- 11月18日内容总结——同步、异步与阻塞、非阻塞的概念、创建进程的多种方式及multiprocessing模块、进程间的数据隔离和IPC机制(队列)、生产者消费者模型、守护进程、僵尸进程、孤儿进程和多进程错乱问题
目录 一.同步与异步 同步 异步 二.阻塞与非阻塞 阻塞 非阻塞 三.综合使用 1.同步阻塞: 2.同步非阻塞: 3.异步阻塞: 4.异步非阻塞: 四.创建进程的多种方式 进程的创建 multipro ...
- ChatGPT:让程序开发更轻松
作者:京东科技 赵龙波 "贾维斯,你在吗?" "随时待命,先生." 类似<钢铁侠>里的人工智能助理贾维斯,ChatGPT或许是你的随时待命的助手.C ...