最近需求需要记录系统日志,在网上查询发现目前有两种主流方式。一种是利用AOP注解实现,一种是利用拦截器实现。

AOP实现的方式更为灵活,但需要为每一个需要记录的方法上加上注解(类似于白名单)。

我这个需求需要记录的是系统操作日志,范围更广,使用拦截器排除特定的Url会更适合(类似于黑名单)。

AOP实现系统操作日志及参考文章https://blog.csdn.net/u011521890/article/details/74990338

异常及错误日志参考我的另一篇文章https://blog.csdn.net/weixin_42456466/article/details/89672890

拦截器实现系统操作日志:

日志拦截器类

这里我省略了写入数据库dao层的操作,直接用logger日志打印出来。


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.HashMap;public class LogInterceptor implements HandlerInterceptor {private final Logger logger = LoggerFactory.getLogger(LogInterceptor.class);@Overridepublic boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler) {SystemOperationLog log = null;try {log = LoggerUtil.getLog(httpServletRequest,(HandlerMethod) handler);} catch (Exception e) {logger.error(e.getLocalizedMessage());}httpServletRequest.setAttribute(LoggerUtil.LOG_OPERATE, log);return true;}@Overridepublic void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, ModelAndView modelAndView){}@Overridepublic void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object handler, Exception e)  {//返回视图时,插入操作日志SystemOperationLog log = (SystemOperationLog) httpServletRequest.getAttribute(LoggerUtil.LOG_OPERATE);if (log == null) {logger.warn("日志信息为空");} else {HashMap<String, Object> logMap = new HashMap<>(8);logMap.put("createTime",log.getCreateTime());logMap.put("ip",log.getIp());logMap.put("description",log.getDescription());logMap.put("operation",log.getOperationType());logMap.put("operator",log.getOperator());logMap.put("result", null == httpServletRequest.getAttribute("flag"));logger.info("执行记录系统操作日志操作{}",logMap);}}}

loggUtil类

这里我获取方法的描述是通过swagger工具中的value注释获取的,自定义log类中的字段根据你的需求来更改。

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import javax.servlet.http.HttpServletRequest;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;public class LoggerUtil {public static final String LOG_OPERATE = "operation";public LoggerUtil() {}public static SystemOperationLog getLog(HttpServletRequest request, HandlerMethod handler) {String description = null;Method method = handler.getMethod();Annotation[] declaredAnnotations = method.getDeclaredAnnotations();for (Annotation annotation : declaredAnnotations) {Class<? extends Annotation> clazz = annotation.annotationType();if ("io.swagger.annotations.ApiOperation".equals(clazz.getName())) {String annotationString = annotation.toString();String responseString = annotationString.substring(annotationString.indexOf("response=class"),annotationString.length());description = responseString.substring(responseString.indexOf("value=")+6,responseString.length()-1);break;}}SystemOperationLog log = new SystemOperationLog();log.setIp(LoggerUtil.getClientIp(request));log.setOperator("operator");log.setOperatorId(request.getHeader("userId"));log.setOperationType(handler.getMethod().getName());log.setDescription(description);log.getParametersMap().putAll(request.getParameterMap());return log;}/*** 获取客户端ip地址** @param request* @return*/public static String getClientIp(HttpServletRequest request) {String ip = request.getHeader("X-Real-IP");if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {return ip;}ip = request.getHeader("X-Forwarded-For");if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {// 多次反向代理后会有多个IP值,第一个为真实IP。int index = ip.indexOf(',');if (index != -1) {return ip.substring(0, index);} else {return ip;}} else {return request.getRemoteAddr();}}}

配置拦截器拦截规则

排除登录接口


import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(new LogInterceptor()).addPathPatterns("/**").excludePathPatterns("/api/login");super.addInterceptors(registry);}
}

自定义log类

import lombok.Data;import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;@Data
public class SystemOperationLog {/*** 操作时间*/private String createTime = Timestamp.valueOf(LocalDateTime.now()).toString();/***操作员*/private String operator;/***操作员id*/private String operatorId;/***客户端ip*/private String ip;/***操作类型*/private String operationType;/***操作描述*/private String description;/***传入参数*/private Map<String, String[]> parametersMap = new HashMap<>();/***是否操作成功*/private Boolean flag;
}

主要是实现 HandlerInterceptor 接口,preHandle方法会在进入调用方法之前执行,afterCompletion会在调用方法结束之后执行。

获取相应的参数途径主要是通过

httpServletRequest.setAttribute("key",Object)方法传参,httpServletRequest.getAttribute(key)方法取参。
(HandlerMethod) handler;Method method = handler.getMethod();通过handler这个参数可以获取被调用的方法及其注解等信息。

系统操作日志实现_JAVA相关推荐

  1. 系统操作日志设计(二)

    上一篇<系统操作日志设计>,已基本介绍了为什么要系统操作日志和设计系统操作日志部分内容,如不清楚系统操作日志的请点这里. :) 通了解<系统操作日志设计>,已基本明确我们不能通 ...

  2. 如何在springboot项目中使用自定义注解实现系统操作日志的功能

    通常我们的项目中都需要记录操作日志,方便回溯问题,找到根源. 因为给项目添加日志记录功能是属于系统级别的功能,所以这个问题我们马上会想到spring的AOP,可以通过切面的形式.那么怎么来实现呢? 先 ...

  3. 华为服务器怎么查看系统日志,查询系统操作日志(operationlog)

    # 查询操作日志. iMana:/->ipmcget -d operationlog -v list 0 Aug 13 23:07:24 iMana bmcipmi.out[354]: Oper ...

  4. 服务器系统操作日志,查询系统操作日志(operationlog)

    # 查询操作日志. iMana:/->ipmcget -d operationlog -v list 0 Aug 13 23:07:24 iMana bmcipmi.out[354]: Oper ...

  5. java 可视化系统操作日志_技术文 | 日志框架使用技巧分享

    原标题:技术文 | 日志框架使用技巧分享 日志的意义 对于一个应用程序来说日志记录是具有重要意义的. 日志通常用于线上问题追踪,协助定位业务问题或程序问题,以及基于日志的业务逻辑统计分析等. java ...

  6. spring aop 实现系统操作日志记录存储到数据库

    1.引入依赖 <!--spring切面aop依赖--> <dependency><groupId>org.springframework.boot</grou ...

  7. 用aspect在springboot中记录操作日志至数据库的详细过程

    代码来自若依管理系统的后台,我截取的其中用于记录操作日志的部分 1.切面 2.操作日志表 3.spring工具类 4.客户端工具类 异步工厂(产生任务用) 异步任务管理器 5.服务层 6.控制层 1. ...

  8. C#+SQL Server数据库系统操作日志的实现完整案例

    在开发数据库系统时,通常需要添加系统日志功能.系统日志是用来记录用户.管理员等对系统的操作记录,系统操作日志的实现方式有很多,本文基于C#和SQL Server数据库,通过设计日志记录表.编写操作记录 ...

  9. 【开源】OSharp3.0框架解说系列(6.2):操作日志与数据日志

    OSharp是什么? OSharp是个快速开发框架,但不是一个大而全的包罗万象的框架,严格的说,OSharp中什么都没有实现.与其他大而全的框架最大的不同点,就是OSharp只做抽象封装,不做实现.依 ...

最新文章

  1. 如何在 1 秒内将 50 个 OpenCV 帧上传到云存储
  2. [Luogu] 1600
  3. sap.ui.viewModifications view extension
  4. 在Windows Live Writer中插入C# code
  5. 庖丁解牛|图解 MySQL 8.0 优化器查询转换篇
  6. php oracle 需要libmysql.dll么_,Windows7环境下Apache+PHP+MySQL完美配置
  7. C++学习系列笔记(二)
  8. RhinoMock入门(6)——安装结果和约束
  9. windows 内核进程的优先级_华为鸿蒙 OS 轻量内核设计理念与关键特性
  10. 书信用语“商祺”是的意思
  11. 如何一站式高效管理固定资产?
  12. 自建网盘教程之:使用可道云搭建私有云网盘,无需数据库
  13. scrapy中文网学习笔记
  14. win7安装wildfly8.1
  15. vite 预编译实现
  16. install在python里什么意思_python setup.py install是什么意思
  17. MR21修改物料标准价
  18. 一文看懂开源许可证丨开源知识科普
  19. QT实现简单的医院管理系统
  20. Matlab相机标定工具箱和标定结果评价

热门文章

  1. 安装linux系统后要做的事情
  2. 田蕴章书法讲座《每日一题,每日一字》(5) 文字整理 -- 一些常用字的写法
  3. 基于QT的智能家居中控系统的简明设计
  4. keep-alive 用法
  5. 蒙特卡洛 pi C语言,python R 实现蒙特卡洛算法计算pi值
  6. 2020蓝桥杯省赛C/C++B组(第二场) 试题A:门牌制作
  7. 用ArrayList 模拟三人斗地主
  8. 从干净SSD安装ubuntu20.04.3 LTS 单系统
  9. Qt构建、运行、qmake的区别
  10. 解决Linux环境下重启后Java环境变量失效