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. 注意看,她叫小美,在地址栏输入URL地址后发生了什么?

    注意看,这个用户叫小美,他在地址栏输入了一串URL地址,然后竟然发生了不可思议的事情! 01.输入URL发生了什么? 从输入URL开始,到页面呈现出来,简单来说分为四个步骤: ① 建立连接:建立与服务 ...

  2. vue下载与安装

    首先安装node.js环境: node.js 安装推荐文章:https://www.cnblogs.com/zhouyu2017/p/6485265.html 基于node.js安装淘宝镜像npm i ...

  3. JAVA中使用最广泛的本地缓存?Ehcache的自信从何而来2 —— Ehcache的各种项目集成与使用初体验

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 在上一篇文章<JAVA中使用最广 ...

  4. Docker 搭建 Wordpress 个人博客

    Docker安装 更新软件库(可选),将所用到的yum软件更新到最新 yum -y update docker一键安装命令: curl -fsSL https://get.docker.com | b ...

  5. java代码的基本组成

    我们可以通过上一篇博客写的内容来分析java代码的组成 java代码的组成我们可以大致分成4个部分 一.标识符 除了关键字(有颜色的,可以看到上方图片)以外,自己们写的单词(黑色部分的),如MyJav ...

  6. Vue 中 Promise 的then方法异步使用及async/await 异步使用总结

    转载请注明出处: 1.Promise 的 then 方法使用 then 方法是 Promise 中 处理的是异步调用,异步调用是非阻塞式的,在调用的时候并不知道它什么时候结束,也就不会等到他返回一个有 ...

  7. 迁移学习(JDDA) 《Joint domain alignment and discriminative feature learning for unsupervised deep domain adaptation》

    论文信息 论文标题:Joint domain alignment and discriminative feature learning for unsupervised deep domain ad ...

  8. Hugging Face 每周速递:Spaces 上边可以跑 Jupyter Notebook;百度 UIE-X 模型展示发布...

    每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...

  9. Array.from() ------来自❀ 前端宇宙 ❀公众号。

    JavaScript 中有一个这样的函数: Array.from:允许在 JavaScript 集合(如: 数组.类数组对象.或者是字符串.map .set 等可迭代对象) 上进行有用的转换. 1. ...

  10. 线上代码已变更,客户没有刷新浏览器,导致点击菜单后找不到相对路由js文件无法加载XXX路由,解决办法如下

    1,reload 方法,该方法强迫浏览器刷新当前页面. 语法:location.reload([bForceGet]) 参数: bForceGet, 可选参数, 默认为 false,从客户端缓存里取当 ...