Spring Boot 日志文件

Spring Boot 日志文件

日志文件是用于记录系统操作事件的记录文件或文件集合,可分为事件日志消息日志。具有处理历史数据、诊断问题的追踪以及理解系统的活动等重要作用。
事件日志记录系统的执行中发生的事件,以便提供可用于理解系统的活动和诊断问题的跟踪。它们对理解复杂系统的活动至关重要,特别是在用户交互较少的应用程序中。
互联网中继聊天(IRC),即时消息(IM)程序,具有聊天功能的对等文件共享客户端和多人游戏(特别是MMORPG)通常具有自动记录(即保存)文本通信的能力。消息日志几乎是通用的纯文本文件,但是IM和VoIP客户端(其支持文本聊天,例如Skype)可以将它们保存在HTML文件中或以自定义格式以便于阅读和加密。

日志级别

几种常见的日志级别由低到高分为:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
如果项目中的日志级别设置为INFO,那么比它更低级别的日志信息就看不到,即TRACE、DEBUG日志将不会显示。

日志框架

Log4j,Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

Logback,Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core, logback-classic和logback-access。logback-corre是其它两个模块的基础模块。logback相比于log4j性能提升了很多,初始化内存加载也更小了,并且作为Spring Boot 的默认日志框架。

Log4j2,Log4j2是对Log4j的升级版本,参考了logback的一些优秀设计,并且修复了一些问题,因此带来一些重大的提升:1.异常处理,在logback中,Appender中的异常不会被应用感知到,但是在log4j2中,提供了一些异常处理机制;2.性能提升,log4j2相较于log4j和logback都具有明显的性能提升;3.自动重载配置,在生产上可以动态的修改日志的级别而不需要重启应用;4.无垃圾机制,log4j2在大部分情况下,都可以使用其设计的一套无垃圾机制【对象重用、内存缓冲】,避免频繁的日志收集导致的jvm gc。

Spring Boot 日志框架

Spring Boot 默认的日志框架是 logback,原则上使用logback需要添加以下依赖,但是Spring Boot使用其作为默认框架,在引入spring boot依赖的时候就引入了logback依赖了,不用再手动引入。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

Spring Boot 中默认的日志级别是INFO,使用初始化日志配置时启动日志打印如下:

2023-01-12 15:13:49.519  INFO 44380 --- [           main] com.example.demo.DemoApplication         : Starting DemoApplication using Java 11.0.16 on user with PID 44380 (E:\java\demo\target\classes started by user in E:\java\demo)
2023-01-12 15:13:49.522  INFO 44380 --- [           main] com.example.demo.DemoApplication         : No active profile set, falling back to 1 default profile: "default"
2023-01-12 15:13:50.020  INFO 44380 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8888 (http)
2023-01-12 15:13:50.026  INFO 44380 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-01-12 15:13:50.026  INFO 44380 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.69]
2023-01-12 15:13:50.083  INFO 44380 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-01-12 15:13:50.083  INFO 44380 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 533 ms
2023-01-12 15:13:50.293  INFO 44380 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8888 (http) with context path ''
2023-01-12 15:13:50.301  INFO 44380 --- [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.064 seconds (JVM running for 1.679)

默认输出的日志元素为:

  • 日期时间:精确到毫秒
  • 日志级别:INFO
  • 进程ID
  • 分隔符:- - - 标识实际日志的开始
  • 线程名:方括号包裹
  • Logger名:通常是源代码的类名
  • 日志内容
代码中使用日志

方式一:
也就是最原始的方式,在每一个类里面添加如下代码:

private final Logger logger = LoggerFactory.getLogger(JavaClass.class);
// 使用logger记录日志
logger.info("这里是记录的日志内容");

这种方式显然比较鸡肋,如果每个类中都添加以下岂不是很low
方式二:
引入lombok依赖

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>

在类上加入注解 @Slf4j

@Slf4j
@RestController
@RequestMapping("demo")
public class DemoController {

    @Autowired
    private UserInfo userInfo;

    @GetMapping("test")
    public String demoTest() {
    	log.info("访问url: http://localhost:8888/demo/test")return JSON.toJSONString(userInfo);
    }
}
定义日志级别

spring boot 的默认日志级别是INFO,但可以自己在配置文件中修改日志级别:

logging:
  level: debug

上面是将所有的日志级别都改成了debug,spring boot还支持package级别的日志级别调整,格式为:logging.level.xxx=xxx

logging:
  level: 
    com.example.demo: error
日志输出到文件中

Spring Boot 中日志默认是输出到控制台的,但是生产环境中这样显示肯定是不行的,因此需要配置日志输出到日志文件中。

logging:
  file:
    # 日志文件的路径(当前项目路径的logs文件夹下)
    path: ./logs
    # 日志文件名,默认为spring,log
    name:

注意:官方文档说 path 和 name 两个属性不能同时配置,否则不生效,因此只需要配置一个即可。

日志格式
logging:
  pattern:
    console: "%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n"
    file: "%d{yyyy/MM/dd-HH:mm:ss} [%thread] %-5level %logger- %msg%n"
  • %d{yyyy/MM/dd-HH:mm:ss} — 日志输出日期时间格式,如 2023-01-12 15:50:00
  • %thread — 输出日志的进程名字,这在Web应用以及异步任务处理中很有用
  • %-5level — 日志级别,并且使用5个字符靠左对齐
  • %logger — 日志输出者的名字
  • %msg — 日志信息
  • %n — 平台的换行符

自定义日志配置

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

当然,如果不想使用spring boot 推荐的名字,也可以在配置文件中指定配置文件的名称即可:

logging.config=classpath:custom-log-file.xml

Spring Boot 官方推荐优先使用带有-spring的文件名作为日志配置,因此只需要在 src/resources 文件夹下创建 logback-spring.xml 文件即可,配置文件内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!--定义日志存放目录-->
    <property name="logPath" value="logs"/>
    <!--日志输出的格式-->
    <property name="PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} %L %M - %msg%xEx%n"/>
    <contextName>logback</contextName>

    <!-- 输出到控制台 -->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 展示格式 layout -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${PATTERN}</pattern>
        </layout>
        <!-- 过滤器,只要过滤到指定级别的日志信息才会输出,如果level为ERROR,控制台只会输出ERROR日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>

    <!-- 输出到文件 -->
    <appender name="fileDEBUGLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 如果只是想要info级别的日志,只是过滤info还是会输出error日志,因为error级别高,使用以下策略会避免输出error日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤error -->
            <level>Error</level>
            <!-- 匹配到就禁止 -->
            <onMatch>DENY</onMatch>
            <!-- 没匹配到就允许 -->
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <!-- 日志名称,如果没有File属性,只会使用FileNamePattern的文件路径规则 -->
        <!-- 如果同时又FileFileNamePattern,当天日志是File,明天会把今天的日志改为今天的日期,File的日志都是当天的 -->
        <File>${logPath}/log_demo.log</File>
        <!-- 滚动策略,按照时间滚动 TimeBaseRollingPolicy -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 文件路径,定义了日志的切分方式,把每天的日志归档到一个文件中,以防止日志填满整个磁盘空间 -->
            <FileNamePattern>${logPath}/log_demo_%d(yyyy-MM-dd).log</FileNamePattern>
            <!-- 只保留最近90天的日志 -->
            <maxHistory>90</maxHistory>
            <!-- 用来指定日志文件的上限大小,到了这个值,就会删除旧的日志 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <!-- 日志编码输出格式化 -->
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- 输出error日志到指定文件中 -->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 如果只是想要Error级别的日志,需要过滤一下,默认是info级别的-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>Error</level>
        </filter>
        <File>${logPath}</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${logPath}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
            <maxHistory>90</maxHistory>
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <charset>UTF-8</charset>
            <pattern>${PATTERN}</pattern>
        </encoder>
    </appender>

    <!--指定最基础的日志输出级别-->
    <root level="DEBUG">
        <!--appender将会添加到这个logger-->
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

    <!--定义指定package的日志级别-->
    <logger name="org.springframework" level="DEBUG"/>
    <logger name="org.mybatis" level="DEBUG"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    <logger name="io.lettuce.*" level="INFO"/>
    <logger name="io.netty.*" level="DEBUG"/>
    <logger name="com.rabbitmq.*" level="DEBUG"/>
    <logger name="org.springframework.amqp.*" level="DEBUG"/>
    <logger name="org.springframework.scheduling.*" level="DEBUG"/>

    <!--定义com.xx.xx包下的日志信息不上传,直接输出到fileDEBUGLog和fileErrorLog这两个appender中,日志级别为DEBUG-->
    <logger name="com.example.demo" additivity="false" level="DEBUG">
        <appender-ref ref="fileDEBUGLog"/>
        <appender-ref ref="fileErrorLog"/>
    </logger>
</configuration>

各配置节点含义:
configuration(根节点)

  • scan: 当此属性为true时,配置文件如果发生改变,将会被重新加载,默认为true
  • scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认时间间隔为1分钟
  • debug:当此属性为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false

root
这是一个必须的节点,用来指定基础的日志级别,只有一个level属性,默认值是DEBUG
该节点可以包含零个或多个元素,字节点是 appender-ref, 标记这个 appender 将会添加到这个 logger

contextName
标识一个上下文名称,默认为 default, 一般用不到

property
标记一个上下文变量,属性有 name 和 value,定义变量之后可以使用 ${} 来获取

appender
用来格式化日志输出节点,有两个属性 name 和 class,class 用来指定哪种输出策略,常用就是控制台输出策略和文件输出策略
这个节点很重要,通常的日志文件需要定义三个 appender,分别是控制台输出、常规日志文件输出和异常日志文件输出
该节点有几个重要子节点:

  • filter:日志输出拦截器,没有特殊定制一般使用系统自带的即可,但是如果要将日志分开,比如将 ERROR 级别的日志输出到一个文件中,将除了 ERROR 级别的日志输出到另外一个文件中,此时就要拦截 ERROR 级别的日志了
  • encoder:和 pattern 节点组合用于具体输出的日志格式和编码格式
  • file:节点用来指明日志文件的输出位置,可以是绝对路径也可以是相对路径
  • rollingPolicy:日志回滚策略,在这里我们用了 TimeBasedRollingPolicy 基于时间的回滚策略有以下子节点 fileNamePattern(必要节点),可以用来设置指定时间的日志归档
  • maxHistory:可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件,例如设置为30的话,30天之后旧的日志就会被删除
  • totalSizeCap:可选节点,用来指定日志文件的上限大小,例如设置为3GB的话,那么到了这个值,就会删除旧的日志

logger
可选节点,用来具体指明包的日志输出级别,它将会覆盖 root 的输出级别
该节点有几个重要子节点:

  • name:指定包名
  • level:可选,日志的级别
  • addtivity:可选,默认为 true,将此 logger 的信息向上级传递,将有 root 节点定义日志打印。如果设置为 false,将不会上传,此时需要定义一个 appender-ref 节点才会输出

日志切换

前面介绍的日志框架都是基于日志门面 SLF4j 即简单日志门面(Simple Logging Facade for Java),SLF4j 并不是一个真正的日志实现,而是一个抽象层,它允许你在后面使用任意一个日志实现
使用了 slf4j 后,对于应用程序来说,无论底层的日志框架如何变,应用程序不需要修改任意一行代码,就可以直接上线了

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值