SpringBoot 异步输出 Logback 日志

字节领航
• 阅读 5947
本文介绍:日志输出到文件并根据LEVEL级别将日志分类保存到不同文件、通过异步输出日志减少磁盘IO提高性能

一、介绍

1.1 Logback

  Logback是由log4j创始人设计的另一个开源日志组件,它分为下面下个模块:

  1. logback-core:其它两个模块的基础模块
  2. logback-classic:它是log4j的一个改良版本,同时它完整实现了slf4j API使你可以很方便地更换成其它日志系统如log4j或JDK14 Logging
  3. logback-access:访问模块与Servlet容器集成提供通过Http来访问日志的功能

1.2 日志级别

包括:TRACEDEBUGINFOWARNERROR

1.2.1 TRACE

特别详细的系统运行完成信息,业务代码中,不要使用。(除非有特殊用意,否则请使用DEBUG级别替代)

1.2.2 DEBUG

  1. 可以填写所有的想知道的相关信息(但不代表可以随便写,debug信息要有意义,最好有相关参数);
  2. 生产环境需要关闭DEBUG信息
  3. 如果在生产情况下需要开启DEBUG,需要使用开关进行管理,不能一直开启。

1.2.3 INFO

  • 系统运行信息

    1. Service方法中对于系统/业务状态的变更;
    2. 主要逻辑中的分步骤。
  • 外部接口部分

    1. 客户端请求参数(REST/WS);
    2. 调用第三方时的调用参数和调用结果。
  • 说明
  1. 并不是所有的service都进行出入口打点记录,单一、简单service是没有意义的;
  2. 对于复杂的业务逻辑,需要进行日志打点,以及埋点记录,比如电商系统中的下订单逻辑,以及OrderAction操作(业务状态变更);
  3. 对于整个系统的提供出的接口(REST/WS),使用INFO记录入参;
  4. 如果所有的service为SOA架构,那么可以看成是一个外部接口提供方,那么必须记录入参;
  5. 调用其他第三方服务时,所有的出参和入参是必须要记录的(因为你很难追溯第三方模块发生的问题)。

1.2.4 WARN

  • 不应该出现但是不影响程序、当前请求正常运行的异常情况:

    1. 有容错机制的时候出现的错误情况;
    2. 找不到配置文件,但是系统能自动创建配置文件;
  • 即将接近临界值的时候,例如:缓存池占用达到警告线;
  • 业务异常的记录,比如:当接口抛出业务异常时,应该记录此异常。

1.2.5 ERROR

影响到程序正常运行、当前请求正常运行的异常情况:

  1. 打开配置文件失败;
  2. 所有第三方对接的异常(包括第三方返回错误码);
  3. 所有影响功能使用的异常,包括:SQLException和除了业务异常之外的所有异常(RuntimeExceptionException)。
不应该出现的情况:
如果进行了抛出异常操作,请不要记录ERROR日志,由最终处理方进行处理:

反例(不要这么做):

try{
    ....
}catch(Exception ex){
  String errorMessage=String.format("Error while reading information of user [%s]",userName);
  logger.error(errorMessage,ex);
  throw new UserServiceException(errorMessage,ex);
}

1.3 SpringBoot 中 logback

  1. SpringBoot工程自带logbackslf4j的依赖,所以重点放在编写配置文件上,需要引入什么依赖,日志依赖冲突统统都不需要我们管了;
  2. logback框架会默认加载classpath下命名为logback-springlogback的配置文件。
  3. 将所有日志都存储在一个文件中文件大小也随着应用的运行越来越大并且不好排查问题,正确的做法应该是将ERROR日志和其他日志分开,并且不同级别的日志根据时间段进行记录存储。

二、logback 配置

2.1 配置文件logback-spring.xml示例

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <!-- 属性文件:在配置文件中找到对应的配置项 -->
    <springProperty scope="context" name="logPath" source="logging.path"/>

    <!-- 输出到控制台 -->
    <appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
        </layout>
    </appender>

    <!-- 获取比info级别高(包括info级别)但除error级别的日志 -->
    <appender name="INFO-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定过滤策略 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <encoder>
            <!-- 指定日志输出格式 -->
            <pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
        </encoder>

        <!-- 指定收集策略:滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 指定生成日志保存地址 -->
            <fileNamePattern>${logPath}/info.%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

    <appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定过滤策略 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <!-- 指定日志输出格式 -->
            <pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.sss}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
        </encoder>
        <!-- 指定收集策略:滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--指定生成日志保存地址 -->
            <fileNamePattern>${logPath}/error.%d.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 异步输出 -->
    <appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="INFO-LOG"/>
    </appender>

    <appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
        <queueSize>256</queueSize>
        <!-- 添加附加的appender,最多只能添加一个 -->
        <appender-ref ref="ERROR-LOG"/>
    </appender>

    <!-- 指定最基础的日志输出级别 -->
    <root level="info">
        <appender-ref ref="CONSOLE-LOG" />
        <appender-ref ref="INFO-LOG" />
        <appender-ref ref="ERROR-LOG" />
    </root>

</configuration>
项目配置文件中配置日志输出地址

logging:
  path: ./logs
    

2.2 标签说明

  • <root>标签:指定最基础的日志输出级别;

    • <appender-ref>标签,添加append
  • <appender>标签:指定日志的收集策略

    1. name属性指定appender命名
    2. class属性指定输出策略,通常有两种,控制台输出和文件输出,文件输出就是将日志进行一个持久化。ConsoleAppender将日志输出到控制台。
  • <filter>标签:指定过滤策略

    • <level>:指定过滤的类型。
  • <encoder>标签:使用该标签下的<pattern>标签指定日志输出格式。
  • <rollingPolicy>标签:指定收集策略,比如基于时间进行收集

    • <fileNamePattern>标签指定生成日志保存地址,实现了按天分类以及日志的目标了。

三、 源码

Github 示例源码

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Easter79 Easter79
3年前
springboot学习(四) 日志管理
1、简介  SpringBoot内部日志系统使用的是CommonsLogging,但开放底层的日志实现。默认为会JavaUtilLogging,Log4J,Log4J2和Logback提供配置。每种情况下都会预先配置使用控制台输出,也可以使用可选的文件输出。 2、日志格式  默认的日志输出格式为:1201
Stella981 Stella981
3年前
Exceptionless
<divid"cnblogs\_post\_body"class"blogpostbodycnblogsmarkdown"<h1id"exceptionless.netcore开源日志框架"Exceptionless.NetCore开源日志框架</h1<blockquote<p作者:markjiang7m2<b
Wesley13 Wesley13
3年前
Log4j
一、log4J的使用步骤1配置文件log4j需要使用配置文件进行配置,共两种方式,一种为properties文件,一种为xml文件。Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG,分别用来指定
Wesley13 Wesley13
3年前
Log4J.xml配置详解
Appender:日志输出器,配置日志的输出级别、输出位置等,包括以下几类:ConsoleAppender:日志输出到控制台;FileAppender:输出到文件;RollingFileAppender:输出到文件,文件达到一定阈值时,自动备份日志文件;DailyRollingFileAppender:可定
Stella981 Stella981
3年前
LogBack入门实践
一、简介LogBack是一个日志框架,它是Log4j作者Ceki的又一个日志组件。LogBack,Slf4j,Log4j之间的关系  slf4j是TheSimpleLoggingFacadeforJava的简称,是一个简单日志门面抽象框架,它本身只提供了日志FacadeAPI和一个简单的日志类实现,一般常配合Lo
Stella981 Stella981
3年前
Logback
1\.作用Logback将写日志事件的任务委托给appender组件完成,SiftingAppender顾名思义就是筛选日志事件,具体点就是:对于Logback委托给它的日志事件,SiftingAppender会对日志事件做一些区分,然后不同的事件SiftingAppender会委托不同的appender去完成真正的写操作。假
Stella981 Stella981
3年前
Spring boot——logback 基础使用篇(一)
1简单日志配置springboot内部使用CommonsLogging来记录日志,但也保留外部接口可以让一些日志框架来进行实现,例如JavaUtilLogging,Log4J2还有Logback。如果你想用某一种日志框架来进行实现的话,就必须先配置,默认情况下,springboot使用Logback作为日志实现的框架。1
Stella981 Stella981
3年前
Linux日志安全分析技巧
0x00前言我正在整理一个项目,收集和汇总了一些应急响应案例(不断更新中)。GitHub地址:https://github.com/Bypass007/EmergencyResponseNotes本文主要介绍Linux日志分析的技巧,更多详细信息请访问Github地址,欢迎Star。0x01日志简介Lin