本篇文章是接着 Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理写的,按照前面几篇博客的教程,可以搭建一个简单的项目,主要包含了 Pagehelper+MyBatis 分页查询,Generator 代码自动生成器,Shiro登录及权限管理。本篇博客主要是集成 AOP 进行日志管理

1.导入 jar 包

  1. <!-- aop -->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-aop</artifactId>
  5. </dependency>

2.配置 Logback-spring 文件

关于 Logback-spring 的配置网上很多,随便copy一份基本上就能使用,Logback-spring.xml 中主要配置了下列内容

  • (1).日志写道控制台
  • (2).日志写道本地文件中
  • (3).日志级别
  • (4).日志生成方式(按照日期滚动生成,还是按照日期单独生成)
  • (5).日志来源的配置,一般直接配置到 Control

我也是直接在copy了一份,代码如下

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <configuration scan="true" scanPeriod="60 seconds" debug="false">
  3. <contextName>logback</contextName>
  4. <!--
  5. &lt;!&ndash; 文件输出格式 &ndash;&gt;
  6. <property name="PATTERN" value="%-12(%d{yyyy-MM-dd HH:mm:ss.SSS}) |-%-5level [%thread] %c [%L] -| %msg%n" />
  7. &lt;!&ndash; test文件路径 &ndash;&gt;
  8. <property name="TEST_FILE_PATH" value="c:/log" />
  9.  
  10. -->
  11.  
  12. <!--输出到控制台-->
  13. <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
  14. <encoder>
  15. <pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
  16. </encoder>
  17. </appender>
  18.  
  19. <!--按天生成日志-->
  20. <appender name="logFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
  21. <Prudent>true</Prudent>
  22. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  23. <FileNamePattern>
  24. applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
  25. </FileNamePattern>
  26. </rollingPolicy>
  27. <layout class="ch.qos.logback.classic.PatternLayout">
  28. <Pattern>
  29. %d{yyyy-MM-dd HH:mm:ss} -%msg%n
  30. </Pattern>
  31. </layout>
  32. </appender>
  33.  
  34. <logger name="com.tswc.edu" additivity="false">
  35. <appender-ref ref="console"/>
  36. <appender-ref ref="logFile" />
  37. </logger>
  38.  
  39. <root level="error">
  40. <appender-ref ref="console"/>
  41. <appender-ref ref="logFile" />
  42. </root>
  43.  
  44. </configuration>

这里用户也可以配置多个级别使用于多个环境,对每个日志级别进行配置不同的属性,然后在 Application.xml 中选择不同的级别环境。在实际项目开发的过程中,一般配置2个环境,开发环境,生产环境。在开发环境中,只需要配置日志输出到控制台,便于开发人员调试。生成环境相反,需要配置日志输出到文件,控制台尽量不要输出日志,这样可以减少控制台对虚拟机内存的消耗,一旦产生 Bug ,用户查询日志文件即可

上述代码中即配置了日志输出到控制台,也配置了日志输出到日志文件

3.配置日志级别

只需要在 Application.xml 中配置即可:

日志级别分为5个等级,debug<info<warn<Error<Fatal,其中常用的级别为:debug和info

  • debug 级别最低,可以随意的使用于任何觉得有利于在调试时更详细的了解系统运行状态的东东;
  • info 重要,输出信息:用来反馈系统的当前状态给最终用户的; 后三个,警告、错误、严重错误,这三者应该都在系统运行时检测到了一个不正常的状态。
  • warn, 可修复,系统可继续运行下去;
  • Error, 可修复性,但无法确定系统会正常的工作下去;
  • Fatal, 相当严重,可以肯定这种错误已经无法修复,并且如果系统继续运行下去的话后果严重。

4.编写日志类

  1. @Aspect
  2. @Component
  3. public class WebLogAspect {
  4.  
  5. private static final Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
  6.  
  7. @Pointcut("execution( * com.tswc.edu.controller.*.*(..))")//两个..代表所有子目录,最后括号里的两个..代表所有参数
  8. public void logPointCut() {
  9. }
  10.  
  11. @Before("logPointCut()")
  12. public void doBefore(JoinPoint joinPoint) throws Throwable {
  13. // 接收到请求,记录请求内容
  14. ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
  15. HttpServletRequest request = attributes.getRequest();
  16.  
  17. // 记录下请求内容
  18. logger.info("请求地址 : " + request.getRequestURL().toString());
  19. //logger.info("方法描述 : " + );
  20. logger.info("HTTP METHOD : " + request.getMethod());
  21. // 获取真实的ip地址
  22. //logger.info("IP : " + IPAddressUtil.getClientIpAddress(request));
  23. logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "."
  24. + joinPoint.getSignature().getName());
  25. logger.info("参数 : " + Arrays.toString(joinPoint.getArgs()));
  26. // loggger.info("参数 : " + joinPoint.getArgs());
  27.  
  28. }
  29.  
  30. @AfterReturning(returning = "ret", pointcut = "logPointCut()")// returning的值和doAfterReturning的参数名一致
  31. public void doAfterReturning(Object ret) throws Throwable {
  32. // 处理完请求,返回内容(返回值太复杂时,打印的是物理存储空间的地址)
  33. logger.debug("返回值 : " + ret);
  34. }
  35.  
  36. @Around("logPointCut()")
  37. public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
  38. long startTime = System.currentTimeMillis();
  39. Object ob = pjp.proceed();// ob 为方法的返回值
  40. logger.info("耗时 : " + (System.currentTimeMillis() - startTime));
  41. return ob;
  42. }
  43. }

这是个通用类,主要约定控制台或者日志文件中日志的格式,关于此公共类,网上有大量的讲解,这里就不详细说明了。

再次启动项目,控制台将输出日志,并将日志写入到文件中:


5.新增加部分

其中自定义日志文件可以不要,这里用户自己定义了日志输出的说明部分
自定义了 @Log 注记的识别,并配置一些文件说明,那么在请求到这个类的时候,日志中将输出文章描述部分

自定义配置文件的代码:

  • Log
  1. @Target(ElementType.METHOD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. //自定义注解类 ArchivesLog.java(获取Controller描述用的)
  4. public @interface Log {
  5. String value() default "";
  6. }
  • LogAspect
  1. public class LogAspect {
  2. private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
  3. //切点
  4. @Pointcut("@annotation(com.tswc.edu.annotation.Log)")
  5. public void logPointCut() {
  6. }
  7.  
  8. @Around("logPointCut()")
  9. public Object around(ProceedingJoinPoint point) throws Throwable {
  10. long beginTime = System.currentTimeMillis();
  11. // 执行方法
  12. Object result = point.proceed();
  13. // 执行时长(毫秒)
  14. long time = System.currentTimeMillis() - beginTime;
  15. //异步保存日志
  16. //saveLog(point, time);
  17. return result;
  18. }
  19.  
  20. }

其中LogAspect中也可以写一些对日志进行 CRUD 的业务逻辑操作,大多数情况下,此处可以将日志的保存逻辑写入到此类中。

6.问题

本项目在启动的时候,报了一个关于日志的警告,没有找到解决方案

项目中并没有用到log4j,不知道为什么会警告,项目中缺少log4j的配置文件,如果有大神知道原因,欢迎留言

Spring Boot 入门(五):集成 AOP 进行日志管理的更多相关文章

  1. Spring Boot入门(五):使用JDBC访问MySql数据库

    本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 在程序开发的过程中,操作数据库是必不可少的部分,前面几篇博客中,也一直未涉及到数据库的操作,本篇博客 就 ...

  2. SpringBoot 源码解析 (十)----- Spring Boot的核心能力 - 集成AOP

    本篇主要集成Sping一个重要功能AOP 我们还是先回顾一下以前Spring中是如何使用AOP的,大家可以看看我这篇文章spring5 源码深度解析----- AOP的使用及AOP自定义标签 Spri ...

  3. Spring boot 入门五:springboot 开启声明式事务

    springboot开启事务很简单,只需要一个注解@Transactional 就可以了.因为在springboot中已经默认对jpa.jdbc.mybatis开启了事务.这里以spring整合myb ...

  4. Spring Boot 入门(六):集成 treetable 和 zTree 实现树形图

    本篇文章是接着Spring Boot 入门(五):集成 AOP 进行日志管理写的,主要集成了树形图,在部门列表或者权限列表中,树形图经常被用上.主要是根据相应的 API 凭借 html 字符串 1.t ...

  5. Spring boot 入门(四):集成 Shiro 实现登陆认证和权限管理

    本文是接着上篇博客写的:Spring boot 入门(三):SpringBoot 集成结合 AdminLTE(Freemarker),利用 generate 自动生成代码,利用 DataTable 和 ...

  6. Spring Boot 入门(八):集成RabbitMQ消息队列

    本片文章续<Spring Boot 入门(七):集成 swagger2>,关于RabbitMQ的介绍请参考<java基础(六):RabbitMQ 入门> 1.增加依赖 < ...

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

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

  8. Spring Boot 入门(十一):集成 WebSocket, 实时显示系统日志

    以前面的博客为基础,最近一篇为Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存.本篇博客主要介绍了Spring Boot集成 Web Socket进行日志的推送, ...

  9. Spring Boot 入门(十三):集成Hasor的Dataway模块,干掉后台,自动配置接口

    终于出湖北了,封闭2个月,家里没电脑,感觉好久没自主撸代码啊啊啊啊啊啊啊啊啊啊啊啊啊. 连接上篇文章Spring Boot 入门(十二):报表导出,对比poi.jxl和esayExcel的效率,继续从 ...

随机推荐

  1. MongoDB 小记

    之前本人说过一款非关系型数据库的代表 Redis 的 < Redis 小记 >文章,觉得意犹未尽,今天就来介绍一款数据库 MongoDB ,先来看一下 MongoDB是一款基于分布式文件存 ...

  2. Flannel工作原理

    flanneld程序启动会有一个参数叫做-etcd-prefix和-iface.前者是指定flanneld程序使用etcd的哪个节点来存储数据,-face是指定flanneld使用网络是使用宿主机哪个 ...

  3. javascript入门篇(三)

    字符串属性和方法 原始值字符串,如'liang', 没有属性和方法(因为他们不是对象). 原始值可以使用 JavaScript 的属性和方法,因为 JavaScript 在执行方法和属性时可以把原始值 ...

  4. 5.1基于JWT的认证和授权「深入浅出ASP.NET Core系列」

    希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. Cookie-Based认证 认证流程 我们先看下传统Web端的认 ...

  5. 关于.net导出数据到excel/word【占位符替换】

    1]excel的占位符替换 效果如图 关键代码: ///savedFilePath需要保存的路径 templateDocPath模板路径 替换的关键字和值 格式 [姓名]$%$小王 public st ...

  6. 将一个html文件引入另一个html文件的div中

    width="" height=""属性可根据要求自己设定

  7. MTK Camera相关的Makefile Option详解

    列举了所有Camera相关的MakefileOption,并对其功能含义和OptionValues做了详细的解释.[KEYWORD]Others[SOLUTION]YUVCAM_INTERPOLATI ...

  8. express+handlebars 快速搭建网站前后台

    最近在重构公司网站,原来网站使用PHP,前后端不分离,添加与更新网站内容仍使用原始方法,先出布局再把调好的布局给PHP后端开发,花时间长,维护不易.因此决定将网站前后端分离,核心功能含网站下单及CRM ...

  9. JavaScript中的 NaN 与 isNaN

    NaN NaN 即 Not a Number ,不是一个数字. 在 JavaScript 中,整数和浮点数都统称为 Number 类型 .除此之外,Number 类型还有一个很特殊的值,即 NaN . ...

  10. Dubbo 支持哪些序列化协议?

    面试题 dubbo 支持哪些通信协议?支持哪些序列化协议?说一下 Hessian 的数据结构?PB 知道吗?为什么 PB 的效率是最高的? 面试官心理分析 上一个问题,说说 dubbo 的基本工作原理 ...