日志通常不会在需求阶段作为一个功能单独提出来,也不会在产品方案中看到它的细节。但是,这丝毫不影响它在任何一个系统中的重要地位。

报警系统与日志系统的关系

为了保证服务的高可用,发现问题一定要及时,定位并解决问题一定要迅速。

生产环境一旦出现问题,预警系统就会通过邮件,短信甚至电话的方式实施多维轰炸模式,确保相关负责人不会错过每一个可能的Bug。

而预警系统判断疑似Bug大部分来源于日志系统。比如说某个微服务接口由于各种原因导致频繁调用出错,此时调用段就会捕获这样的异常并打印ERROR级别的日子,当该错误日志达到一定出现次数的时候就会触发报警系统。

  1. try {
  2. // 调用某服务
  3. } catch(Exception e) {
  4. Logger.error("错误信息", e);
  5. }

因此日志十分重要。

Spring Boot的默认日志

Spring Boot默认使用Logback日志系统,如果不需要更改为其他日志系统,如Log4j2等,则无需多余的配置,Logback默认将日志打印到控制台上。

要使用Logback,原则上是需要添加Maven依赖的。

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

但是由于Spring Boot项目中一般会引用spring-boot-starter或spring-boot-starter-web,这两个起步依赖中都已经包含了对spring-boot-starter-logging的依赖,所以无需额外添加依赖,配置logback-spring.xml就可以了。以logback-spring.xml命名,spring会自动识别加载。

如果要切换成Log4j2的话,就需要在pom.xml中排除Spring Boot自带的commons-logging,然后再引入log4j2的依赖,否则会导致jar包冲突。

  1. <!--排除 commons‐logging-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-web</artifactId>
  5. <exclusions>
  6. <exclusion>
  7. <groupId>commons‐logging</groupId>
  8. <artifactId>commons‐logging</artifactId>
  9. </exclusion>
  10. </exclusions>
  11. </dependency>
  12.  
  13. <!--引入log4j2 -->
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-log4j2</artifactId>
  17. </dependency>

然后再引入log4j.properties文件就可以了。

  1. ### set log levels ###
  2. log4j.rootLogger = debug,stdout,D,E
  3.  
  4. ### 输出到控制台 ###
  5. log4j.appender.stdout = org.apache.log4j.ConsoleAppender
  6. log4j.appender.stdout.Target = System.out
  7. log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
  8. log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} ===== %5p %c{ 1 }:%L - %m%n
  9.  
  10. ### 输出到日志文件 ###
  11. #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  12. #log4j.appender.D.File = logs/log.log
  13. #log4j.appender.D.Append = true
  14. #log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志
  15. #log4j.appender.D.layout = org.apache.log4j.PatternLayout
  16. #log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
  17.  
  18. ### 保存异常信息到单独文件 ###
  19. #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
  20. #log4j.appender.D.File = logs/error.log ## 异常日志文件名
  21. #log4j.appender.D.Append = true
  22. #log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!!
  23. #log4j.appender.D.layout = org.apache.log4j.PatternLayout
  24. #log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n

日志的级别

日志的级别从低到高:trace(跟踪)<debug(调试)<info(信息)<warm(警告)<error(错误),设置的级别越低,显示的日志级别的信息越多。例如如果设置的日志级别是info的话,低于info级别的trace或debug的日志都不会显示。

Spring Boot在不对日志进行任何设置的情况下,默认的日志root级别是info,即输出的是info级别及以上的日志。

用一个测试类来测试日志的输出级别:

  1. @RunWith(SpringRunner.class)
  2. @SpringBootTest
  3. public class SpringbootCacheApplicationTests {
  4. private static final Logger log = LoggerFactory.getLogger(SpringbootCacheApplicationTests.class);
  5.  
  6. /**
  7. * 测试 日志级别:
  8. * 级别由低到高: trace < debug < info < warm < error 设置的级别越低显示的日志信息越多。
  9. * 可以调整输出的日志级别,只会显示高于设置级别的日志。
  10. */
  11. @Test
  12. public void testLog() {
  13. log.trace("这是trace日志。。。");
  14. log.debug("这是debug日志。。。");
  15. // spring 默认设置的级别是info级别,没有指定级别的情况下,会使用spring默认的root级别(显示的是info级别的信息)
  16. log.info("这是info日志。。。");
  17. log.warn("这是warm日志。。。");
  18. log.error("这是error日志。。。");
  19. }
  20.  
  21. }

测试的结果是只会输出info级别以上的日志信息(trace和debug不打印在控制台)。因此在开发环境中如果要打印SQL语句等debug调试信息的话,就要对日志级别进行设置。

日志输出信息的组成部分

1.时间日期:精确到毫秒。

2.日志级别:ERROR, WARN, INFO, DEBUG 或 TRACE。

3.分隔符:标识实际日志的开始。

4.进程ID。

5.线程名:需要用方括号括起来,不然可能会截断控制台的输出。

6.Logger的名称:通常是源代码的类名。

7.日志主要内容。

日志的配置

日志可以通过两种方式配置,一种是application.properties或application.yml文件配置(Spring Boot全局配置文件);一种是Logback的xml文件配置。第一种方式需要把所有的日志配置写在properties或者yml文件里面,配置迁移不方便,写的感觉也有点乱,很繁杂,对log4j2的支持也不好。因此推荐使用的是第二种,配置迁移只要复制粘贴,然后改一下里面的配置就好了。

通过application.properties或application.yml文件配置。

这部分的内容就不说了,实际中用得比较少(其实是懒),如果需要的话可以到Spring Boot的官方文档中查找相关的配置:https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/html/boot-features-logging.html#_environment_properties

通过Logback的xml文件配置。

由于日志服务一般都在ApplicationContext(应用上下文)创建前就初始化了,它并不是必须通过Spring的配置文件控制。因此通过系统属性和传统的Spring Boot外部配置文件依然可以很好地支持日志控制和日志管理。

根据不同的日志系统,只要按照指定的规则组织配置文件名,就能被正常加载。

Logback

logback-spring.xml

logback-spring.groovy

logback.xml

logback.groovy

Log4j

log4j-spring.properties

log4j-spring.xml

log4j.properties

log4j.xml

Log4j2

log4j2-spring.xml

log4j2.xml

JDK (Java Util Logging) logging.properties

Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的日志配置文件,Spring Boot可以为它添加一些Spring Boot特有的配置项(下面会提到)。

一般情况下都是按照默认的命名规则去命名,并把文件放在src/main/resources目录下面即可。但是如果你想要完全掌控日志配置,但是又不想用locagback.xml作为Logback配置的名字,就需要通过logging.config属性去执行自定义的名字,例如:

  1. logging.config=classpath:logging-config.xml

虽然一般是并不需要改变配置文件的名字,但是如果你想要针对不同运行时Profile(不同的环境,比如生产环境和开发环境的切换)使用不同的日志配置,这个功能就会很有用。

这里示例一个logback-spring.xml的配置文件的内容:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
  4. scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
  5. debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
  6. -->
  7. <configuration scan="false" scanPeriod="60 seconds" debug="false">
  8. <!-- 定义日志的根目录 -->
  9. <property name="LOG_HOME" value="/app/log" />
  10. <!-- 定义日志文件名称 -->
  11. <property name="appName" value="ll-springboot"></property>
  12. <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
  13. <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
  14. <!--
  15. 日志输出格式:
  16. %d表示日期时间,
  17. %thread表示线程名,
  18. %-5level:级别从左显示5个字符宽度
  19. %logger{50} 表示logger名字最长50个字符,否则按照句点分割。
  20. %msg:日志消息,
  21. %n是换行符
  22. -->
  23. <layout class="ch.qos.logback.classic.PatternLayout">
  24. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
  25. </layout>
  26. </appender>
  27.  
  28. <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
  29. <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
  30. <!-- 指定日志文件的名称 -->
  31. <file>${LOG_HOME}/${appName}.log</file>
  32. <!--
  33. 当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
  34. TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
  35. -->
  36. <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  37. <!--
  38. 滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动
  39. %i:当文件大小超过maxFileSize时,按照i进行文件滚动
  40. -->
  41. <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
  42. <!--
  43. 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
  44. 且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
  45. 那些为了归档而创建的目录也会被删除。
  46. -->
  47. <MaxHistory>365</MaxHistory>
  48. <!--
  49. 当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
  50. -->
  51. <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
  52. <maxFileSize>100MB</maxFileSize>
  53. </timeBasedFileNamingAndTriggeringPolicy>
  54. </rollingPolicy>
  55. <!-- 日志输出格式: -->
  56. <layout class="ch.qos.logback.classic.PatternLayout">
  57. <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
  58. </layout>
  59. </appender>
  60.  
  61. <!--
  62. logger主要用于存放日志对象,也可以定义日志类型、级别
  63. name:表示匹配的logger类型前缀,也就是包的前半部分
  64. level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
  65. additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,
  66. false:表示只用当前logger的appender-ref,
  67. true:表示当前logger的appender-ref和rootLogger的appender-ref都有效
  68. -->
  69. <!--
  70. logger是记录Logger对象输出的日志级别的
  71.   sercvice实现类引入日志对象可以查看方法的报错信息以及打印sql语句,public static final Logger logger = LoggerFactory.getLogger(SysUserServiceImpl.class);
  72.    生产环境:
  73.        一般把level设为error,可以记录错误的日志信息,毕竟主要是要记录错误信息进行错误定位。
  74.      开发环境:
  75.        类中引入了logger日志对象时,level级别用info,debug都可以,都有错误信息输出。
  76.    -->
  77. <!-- hibernate logger -->
  78. <logger name="com.ll" level="info" />
  79. <!-- Spring framework logger -->
  80. <logger name="org.springframework" level="debug" additivity="false"></logger>
  81.  
  82. <!--
  83. root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
  84. 要么是定义的logger,要么是root,判断的关键在于找到这个logger,然后判断这个logger的appender和level。
  85. -->
  86.   <!-- 一般用默认的info就可以 -->
  87. <root level="info">
  88. <!-- 控制台输出日志-->
  89. <appender-ref ref="stdout" />
  90. <!--
  91. 开发环境:
  92. 不需要往文件记录日志,可以把这个appender-ref ref="appLogAppender"注释,上面那个往文件写日志的appender也要注释,不然每天都产生一个空文件;
  93. 生产环境:
  94. 需要往文件记录日志,此时appender-ref ref="appLogAppender"就不能注释了,不然没日志记录到文件,上面那个往文件写日志的appender也要放开。
  95. -->
  96. <appender-ref ref="appLogAppender" />
  97. </root>
  98. </configuration>

配置文件其实不需要记太多东西,只要知道在什么地方要改什么配置就行了。

日志的使用

在完成了日志系统的配置之后,就可以愉快地享受日志系统带来的快乐了(滑稽)。

日志系统的使用方法就是在业务代码中使用Logger对象调用相应的方法完成日志的输出。

声明并初始化一个Logger对象。

  1. public static final Logger logger = LoggerFactory.getLogger(日志要监控的类.class);

调用相应的方法输出日志。

  1. try {
  2. // 业务代码
  3. } catch(Exception e) {
  4. logger.error("你的代码出错了,笨蛋。", e);
  5. }

这样就能在程序运行时输出相应的日志信息。

"我一个人在路上,偶尔想起你。"

spring boot中的日志入门的更多相关文章

  1. spring boot中配置日志log和热部署

    Java的日志有很多 个人强烈不推荐log4j ,推荐log4j2和logback 在高并发,多线程的环境下log4j1 的性能和log4j2相比可以用junk来形容  对就是junk.log4j2的 ...

  2. 【spring boot logback】spring boot中logback日志乱码问题

    在初次使用logback的自定义配置文件完整的控制spring boot日志后,发现了一个无法忍受的问题,就是日志乱码. 控制台看到打印日志乱码如下: 而日志文件打开: 记事本打开 sublime打开 ...

  3. Spring boot中使用log4j

    我们知道,Spring Boot中默认日志工具为logback,但是对于习惯了log4j的开发者,Spring Boot依然可以很好的支持,只是需要做一些小小的配置功能.Spring Boot使用lo ...

  4. Spring boot中使用log4j记录日志

    之前在Spring Boot日志管理一文中主要介绍了Spring Boot中默认日志工具(logback)的基本配置内容.对于很多习惯使用log4j的开发者,Spring Boot依然可以很好的支持, ...

  5. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  6. Spring Boot中使用AOP统一处理Web请求日志

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是Spring框架中的一个重要内容,它通 ...

  7. Spring Boot中对log4j进行多环境不同日志级别的控制

    之前介绍了在<Spring boot中使用log4j记录日志>,仅通过log4j.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需 ...

  8. Spring Boot中使用AOP记录请求日志

    这周看别人写的springboot后端代码中有使用AOP记录请求日志,以前没接触过,因此学习下. 一.AOP简介 AOP为Aspect Oriented Programming的缩写,意为:面向切面编 ...

  9. 46. Spring Boot中使用AOP统一处理Web请求日志

    在之前一系列的文章中都是提供了全部的代码,在之后的文章中就提供核心的代码进行讲解.有什么问题大家可以给我留言或者加我QQ,进行咨询. AOP为Aspect Oriented Programming的缩 ...

随机推荐

  1. CTF必备技能丨Linux Pwn入门教程——ROP技术(上)

    Linux Pwn入门教程系列分享如约而至,本套课程是作者依据i春秋Pwn入门课程中的技术分类,并结合近几年赛事中出现的题目和文章整理出一份相对完整的Linux Pwn教程. 教程仅针对i386/am ...

  2. ANDROID培训准备资料之项目结构简单介绍

    Android Studio项目结构初步主要介绍下面几个文件夹,后续再补充 (1)java文件夹的介绍 (2)Res文件夹的介绍 (3)R文件的介绍 (4)Manifests文件夹的介绍 我们先看看整 ...

  3. python从入门到放弃之守护进程

    # ### 守护进程 默认情况下,主进程要等待所有子进程执行完毕之后,才会关闭程序,释放资源守护进程进行在主进程代码执行结束之后,就直接关闭;守护进程守护的是主进程 语法: 进程.daemon = T ...

  4. 8. [mmc subsystem] host(第二章)——sdhci

    一.sdhci core说明 1.sdhci说明 具体参考<host(第一章)--概述> SDHC:Secure Digital(SD) Host Controller,是指一套sd ho ...

  5. Ubuntu安装MDK

    1 环境部署 [x] Ubuntu 18.04 [x] Wine 3.0.4 1.0 查看CPU信息 lscpu 序号 属性 描述 1 架构 x86_64 2 CPU 运行模式 32-bit, 64- ...

  6. 使用ruamel.yaml库,解析yaml文件

    在实现的需求如下: 同事提供了一个文本文件,内含200多个host与ip的对应关系,希望能在k8s生成pod时,将这些对应关系注入到/etc/hosts中. 网上看文档,这可以通过扩充pod中的hos ...

  7. 使用gdb添加断点的几种方式

    1. 普通断点 根据代码行数设置断点是最常见的一种方式,在debug程序运行前就可以进行断点的配置.如: (gdb) b src/main.cpp:127 当程序执行到main.cpp文件的第127行 ...

  8. MySQL拓展 视图,触发器,事务,存储过程,内置函数,流程控制,索引,慢查询优化,数据库三大设计范式

    视图: 1.什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次直接使用即可 2.为什么要用视图 如果要频繁使用一张虚拟表,可以不用重复查询 3.如何使用视图 create view tea ...

  9. 子进程回收资源两种方式,僵尸进程与孤儿进程,守护进程,进程间数据隔离,进程互斥锁,队列,IPC机制,线程,守护线程,线程池,回调函数add_done_callback,TCP服务端实现并发

    子进程回收资源两种方式 - 1) join让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源. - 2) 主进程 “正常结束” ,子进程与主进程一并被回收资源. from multipr ...

  10. 【Oracle】Windows启动

    cd D:\app\Administrator\product\\dbhome_1\BIN D: sqlplus /nolog conn sys/system as sysdba startup pf ...