SpringBoot中日志选择与实现

简介: SpringBoot中日志选择与实现

【1】常见的日志门面与实现框架

日志门面 实现框架
JCL(Jakarta Commons logging),SLF4J,Jboss logging Log4j,Log4j2,Logback,JUL(java.util.logging)


其中 SLF4j(门面),Log4j(实现框架),Logback(实现框架)均为一人所写,Logback是Log4j的升级版,而Log4j2则是Apache借用Log4j的名出的日志框架。


每一个日志的实现框架都有自己的配置文件。日志配置文件还是做成日志实现框架自己本身的配置文件。


Spring框架默认使用(commons-logging)即JCL,Hibernate框架默认使用(jboss-logging)。


【2】SpringBoot默认日志选择

查看SpringBoot依赖结构图:


其日志依赖如下:

如上图所示,SpringBoot默认使用的是SLF4J(日志门面)+logback日志实现框架。


其中jul-to-slf4j表示使用slf4j替换掉java.util.logging,log4j-over-slf4j表示使用slf4j替换掉log4j,jcl-over-slf4j表示使用slf4j替换掉java.commongs.logging。这里使用“替换”或许比较难理解,这是slf4j提供的一种桥接模式,对外统一使用slf4j门面。



如果引入其他日志框架,一定要把这个框架的默认日志实现依赖移除掉。如Spring默认使用java.commons.logging。


spring-boot-starter-1.5.9.RELEASE.pom文件如下:

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <exclusions>
        <exclusion>
          <groupId>commons-logging</groupId>
          <artifactId>commons-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可。


【3】默认日志配置与实现

SpringBoot中日志等级如下:


日志使用示例如下:

//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
  //System.out.println();
  //日志的级别;
  //由低到高 trace<debug<info<warn<error
  //可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效
  logger.trace("这是trace日志...");
  logger.debug("这是debug日志...");
  //SpringBoot默认给我们使用的是info级别的,
  //没有指定级别的就用SpringBoot默认规定的级别;root级别
  logger.info("这是info日志...");
  logger.warn("这是warn日志...");
  logger.error("这是error日志...");
}


修改默认日志输出:

SpringBoot默认将日志输出到控制台,可以在全局配置文件中通过logging.path或logging.file来指定日志输出位置。


示例如下:

# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=G:/springboot.log
# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;
#使用?spring.log 作为默认文件
logging.path=/spring/log


添加自定义日志配置文件

根据具体底层日志实现框架不同,在类路径下添加对应的日志配置文件,如下图所示。


具体示例如下:


【4】logback-spring.xml示例

日志输出格式


  • %date:表示日期时间,
  • %thread:表示线程名,
  • %-5level:级别从左显示5个字符宽度
  • %logger{50}:表示logger名字最长50个字符,否则按照句点分割。
  • %method:表示方法名字
  • %line:表示第几行
  • %msg:日志消息,
  • %n是换行符
#如下所示一个常见日志实例
%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - [%method,%line] - %msg%n

配置文件实例

<?xml version="1.0" encoding="UTF-8"?>
<!--
scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒当scan为true时,此属性生效。默认的时间间隔为1分钟。
debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<configuration scan="false" scanPeriod="60 seconds" debug="false">
    <!-- 定义日志的根目录 -->
    <property name="LOG_HOME" value="/app/log" />
    <!-- 定义日志文件名称 -->
    <property name="appName" value="springboot"></property>
    <!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
    <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <springProfile name="dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
            <springProfile name="!dev">
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
            </springProfile>
        </layout>
    </appender>
    <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->  
    <appender name="appLogAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 指定日志文件的名称 -->
        <file>${LOG_HOME}/${appName}.log</file>
        <!--
        当发生滚动时,决定 RollingFileAppender 的行为,涉及文件移动和重命名
        TimeBasedRollingPolicy: 最常用的滚动策略,它根据时间来制定滚动策略,既负责滚动也负责出发滚动。
        -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--
            滚动时产生的文件的存放位置及文件名称 %d{yyyy-MM-dd}:按天进行日志滚动 
            %i:当文件大小超过maxFileSize时,按照i进行文件滚动
            -->
            <fileNamePattern>${LOG_HOME}/${appName}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <!-- 
            可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件。假设设置每天滚动,
            且maxHistory是365,则只保存最近365天的文件,删除之前的旧文件。注意,删除旧文件是,
            那些为了归档而创建的目录也会被删除。
            -->
            <MaxHistory>365</MaxHistory>
            <!-- 
            当日志文件超过maxFileSize指定的大小是,根据上面提到的%i进行日志文件滚动 注意此处配置SizeBasedTriggeringPolicy是无法实现按文件大小进行滚动的,必须配置timeBasedFileNamingAndTriggeringPolicy
            -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 日志输出格式: -->     
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [ %thread ] - [ %-5level ] [ %logger{50} : %line ] - %msg%n</pattern>
        </layout>
    </appender>
    <!-- 
    logger主要用于存放日志对象,也可以定义日志类型、级别
    name:表示匹配的logger类型前缀,也就是包的前半部分
    level:要记录的日志级别,包括 TRACE < DEBUG < INFO < WARN < ERROR
    additivity:作用在于children-logger是否使用 rootLogger配置的appender进行输出,
      false:表示只用当前logger的appender-ref,
      true:表示当前logger的appender-ref和rootLogger的appender-ref都有效
    -->
    <!-- hibernate logger -->
    <logger name="org.hibernate" level="debug" />
    <!-- Spring framework logger -->
    <logger name="org.springframework" level="debug" additivity="false"></logger>
    <!-- 
    root与logger是父子关系,没有特别定义则默认为root,任何一个类只会和一个logger对应,
    要么是定义的logger,要么是root(有logger则根据logger否则根据root)
    判断的关键在于找到这个logger,然后判断这个logger的appender和level。 
    -->
    <root level="info">
        <appender-ref ref="stdout" />
        <appender-ref ref="appLogAppender" />
    </root>
</configuration> 

日志打印控制台

<!-- ch.qos.logback.core.ConsoleAppender 表示控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
   <layout class="ch.qos.logback.classic.PatternLayout">
       <springProfile name="dev">
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
       </springProfile>
       <springProfile name="!dev">
           <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
       </springProfile>
   </layout>
</appender>


按天分割日志保存到文件

 <!--按天生成日志-->
<appender name="logFile"  class="ch.qos.logback.core.rolling.RollingFileAppender">
   <Prudent>true</Prudent>
   <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
       <FileNamePattern>
           applog/%d{yyyy-MM-dd}/%d{yyyy-MM-dd}.log
       </FileNamePattern>
   </rollingPolicy>
   <layout class="ch.qos.logback.classic.PatternLayout">
       <Pattern>
           %d{yyyy-MM-dd HH:mm:ss} -%msg%n
       </Pattern>
   </layout>
</appender>

【5】logback与logback-spring区别

首先呢,二者都可以作为日志框架配置文件正常使用。

其次二者不同如下:

logback.xml:直接就被日志框架识别了;

logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能。


如下所示,在不同环境下使用不同的日志输出格式:

<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
  <springProfile name="dev">
  <pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %‐5level%logger{50} ‐ %msg%n</pattern>
  </springProfile>
  <springProfile name="!dev">
  <pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level
  %logger{50} ‐ %msg%n</pattern>
  </springProfile>
</layout>
</appender>

【6】切换日志框架

① 使用slf4j+log4j

默认日志依赖图如下:


如果想要使用slf4j+log4j替换slf4j+logback日志实现,则需要根据slf4j+log4j的日志适配图在pom文件中进行调整。

slf4j+log4j的日志适配图如下:


调整如下:去掉红色框的依赖,还要添加slfj-log412适配层。

配置适配层依赖

    <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

其中slf4j-log4j12版本由SpringBoot控制,且自动导入了具体实现log4j。

slf4j-log4j12-1.7.25.pom如下:

  <dependencies>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <type>test-jar</type>
      <version>${project.version}</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

此时pom日志依赖树如下图:


在类路径下添加log4j的配置文件即可:

② 使用Log4j2

SpringBoot默认使用spring-boot-starter-logging,也可以使用spring-boot-starter-log4j2进行替换。



修改pom文件:

     <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!--<exclusions>-->
                <!--<exclusion>-->
                    <!--<artifactId>logback-classic</artifactId>-->
                    <!--<groupId>ch.qos.logback</groupId>-->
                <!--</exclusion>-->
                <!--<exclusion>-->
                    <!--<artifactId>log4j-over-slf4j</artifactId>-->
                    <!--<groupId>org.slf4j</groupId>-->
                <!--</exclusion>-->
            <!--</exclusions>-->
            <exclusions>
                <exclusion>
                    <artifactId>spring-boot-starter-logging</artifactId>
                    <groupId>org.springframework.boot</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.slf4j</groupId>-->
            <!--<artifactId>slf4j-log4j12</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

此时系统日志依赖树如下:

同样,在类路径下添加自定义的日志配置文件即可。

【7】一个详细的loback-spring.xml示例

<?xml version="1.0" encoding="UTF-8"?>
<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。 当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
<configuration scanPeriod="10 seconds" scan="true" >
    <contextName>logback</contextName>
    <!--日志路径-->
    <springProfile name="dev">
        <property name="log.path" value="./logs" />
    </springProfile>
    <springProfile name="test,prod">
        <property name="log.path" value="./logs" />
    </springProfile>
    <!--0. 日志格式和颜色渲染 -->
    <!-- 彩色日志依赖的渲染类 -->
    <conversionRule converterClass="org.springframework.boot.logging.logback.ColorConverter" conversionWord="clr"/>
    <conversionRule converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" conversionWord="wex"/>
    <conversionRule converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" conversionWord="wEx"/>
    <!-- 彩色日志格式 -->
    <property value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" name="CONSOLE_LOG_PATTERN"/>
    <!--1. 输出到控制台-->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
        <encoder>
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 设置字符集 -->
            <charset>UTF-8</charset>
        </encoder>
    </appender>
    <!--2. 输出到文档-->
    <!-- 2.1 level为 DEBUG 日志,时间滚动输出 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${log.path}/debug.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
            <!-- 设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志归档 -->
            <fileNamePattern>${log.path}/debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录debug级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 2.2 level为 INFO 日志,时间滚动输出 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${log.path}/info.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志归档路径以及格式 -->
            <fileNamePattern>${log.path}/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录info级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 2.3 level为 WARN 日志,时间滚动输出 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${log.path}/warn.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
            <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录warn级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 2.4 level为 ERROR 日志,时间滚动输出 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在记录的日志文档的路径及文档名 -->
        <file>${log.path}/error.log</file>
        <!--日志文档输出格式-->
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
            <!-- 此处设置字符集 -->
        </encoder>
        <!-- 日志记录器的滚动策略,按日期,按大小记录 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>50MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文档保留天数-->
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <!-- 此日志文档只记录ERROR级别的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。
    <logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。
    name:用来指定受此logger约束的某一个包或者具体的某一个类。
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
    还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
    如果未设置此属性,那么当前logger将会继承上级的级别。
    addtivity:是否向上级logger传递打印信息。默认是true。
    <logger name="org.springframework.web" level="info"/>
    <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
    -->
    <!-- 使用mybatis的时候,sql语句是debug下才会打印,
    而这里我们只配置了info,
    所以想要查看sql语句的话,有以下两种操作:
    第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,
    不过这样日志那边会出现很多其他消息
    第二种就是单独给dao下目录配置debug模式,
    代码如下,这样配置sql语句会打印,其他还是正常info级别:
    【logging.level.org.mybatis=debug logging.level.dao=debug】
    -->
    <!-- root节点是必选节点,用来指定最基础的日志输出级别,
    只有一个level属性 level:用来设置打印级别,
    大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
    不能设置为INHERITED或者同义词NULL。
    默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 -->
    <!-- 4. 最终的策略 -->
    <!-- 4.1 开发环境:打印控制台-->
    <springProfile name="dev">
        <logger name="com.jane" level="debug"/>
        <logger name="springfox.documentation" level="error"/>
        <logger name="org.springframework.web.servlet.mvc.method.annotation" level="error"/>
        <logger name="org.springframework.context.support" level="error"/>
        <root level="info">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>
    <!-- 4.2 生产环境:输出到文档 -->
    <springProfile name="prod,test">
        <logger name="springfox.documentation" level="error"/>
        <root level="info">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="ERROR_FILE" />
            <appender-ref ref="WARN_FILE" />
        </root>
    </springProfile>
</configuration>

【8】一份详细的logback.xml示例

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
  <property name="log.path" value="./logs" />
    <!-- 日志输出格式 -->
  <property name="log.pattern" value="%date{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
  <!-- 控制台输出 -->
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${log.pattern}</pattern>
    </encoder>
  </appender>
  <!-- 系统日志输出 -->
  <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${log.path}/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
      <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd HH:mm:ss.SSS}-%i.log</fileNamePattern>
      <!-- 日志最大的历史 60天 -->
      <maxHistory>60</maxHistory>
      <!-- 单个日志文件最大100MB-->
       <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
    <encoder>
      <pattern>${log.pattern}</pattern>
    </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
  </appender>
  <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
      <!-- 日志最大的历史 60天 -->
      <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
      <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
      <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
  <!-- 用户访问日志输出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
  <!-- 系统模块日志级别控制  -->
  <logger name="com.jane" level="info" />
  <!-- Spring日志级别控制  -->
  <logger name="org.springframework" level="warn" />
  <root level="info">
    <appender-ref ref="console" />
  </root>
  <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>
  <!--系统用户操作日志-->
    <logger name="sys-user" level="info">
        <appender-ref ref="sys-user"/>
    </logger>
</configuration> 

【9】logback设置日志格式为json

① 添加pom依赖

<!--日志格式化-->
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>5.0</version>
</dependency>

② 修改logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
  <property name="log.path" value="./logs" />
    <!-- 日志输出格式 -->
  <property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
  <!-- 控制台输出 -->
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${log.pattern}</pattern>
    </encoder>
  </appender>
  <!-- 系统日志输出 -->
  <appender name="file_debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${log.path}/sys-debug.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
      <fileNamePattern>${log.path}/sys-debug.%d{yyyy-MM-dd}.log</fileNamePattern>
      <!-- 日志最大的历史 60天 -->
      <maxHistory>60</maxHistory>
    </rollingPolicy>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <pattern>
                        {
                            "time": "%date{yyyy-MM-dd HH:mm:ss.SSS}",
                            "thread": "%thread",
                            "level": "%level",
                            "pid": "${PID:-}",
                            "logger": "%logger{64}",
                            "method": "%method",
                            "line": "%line",
                            "message": "%message",
                            "statck_trace": "%exception{5}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>DEBUG</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>ACCEPT</onMismatch>
        </filter>
  </appender>
  <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
      <!-- 日志最大的历史 60天 -->
      <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
      <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
      <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
  <!-- 系统模块日志级别控制  -->
  <logger name="com" level="debug" />
  <!-- Spring日志级别控制  -->
  <logger name="org.springframework" level="debug" />
  <!--系统操作日志-->
    <root level="debug">
        <appender-ref ref="console" />
        <appender-ref ref="file_debug" />
    </root>
</configuration> 

这里主要是<encoder charset="UTF-8" class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">.....,下面pattern指定了json格式。


日志文件里面格式如下图:


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
2月前
|
Java Spring
spring boot 配置log4j 日志
spring boot 配置log4j 日志
34 0
|
2月前
|
运维 Java 程序员
SpringBoot —— 日志基本操作
SpringBoot —— 日志基本操作
24 0
|
28天前
|
Java Spring
【Spring Boot】logback和log4j日志异常处理
【1月更文挑战第25天】【Spring Boot】logback和log4j日志异常处理
|
3月前
|
Java
SpringBoot 日志终极解决方案
SpringBoot 日志终极解决方案
31 0
|
4月前
|
Java 测试技术 Docker
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
Spring Boot 学习研究笔记(十九)-docker部署SpringBoot 日志目录挂载
187 0
QGS
|
27天前
|
Java 数据库连接 Apache
Springboot日志框架logback与log4j2
Springboot日志框架logback与log4j2
QGS
24 0
|
28天前
|
存储 监控 安全
【Spring】SpringBoot日志
【Spring】SpringBoot日志
|
1月前
|
Java Unix 网络安全
Spring Boot整合Log4j做日志处理
Spring Boot整合Log4j做日志处理
29 0
|
1月前
|
XML Java API
忽视日志吃大亏,手把手教你玩转 SpringBoot 日志
一、日志重要吗 程序中的日志重要吗? 在回答这个问题前,笔者先说个事例: ❝ 笔者印象尤深的就是去年某个同事,收到了客户反馈的紧急bug。尽管申请到了日志文件,但因为很多关键步骤没有打印日志,导致排查进度很慢,数个小时都没能排查到问题,也无法给出解决对策。导致了客户程序一直阻断,最终产生了不少损失。 事后,经过仔细推敲,成功复现了这个bug,其实是一个很不起眼的数据转换导致的。可因为日志内容的匮乏,排查起来难度很大。其实只要在数据转换前后进行日志输出,这个问题就是一样的事。但可惜没如果,故事的最后,开发部门还是遭到了客户的投诉,影响到了部门绩效 ❞
|
1月前
|
Java 应用服务中间件 容器
SpringBoot 各种 Web 容器服开启 AccessLog 日志
SpringBoot 各种 Web 容器服开启 AccessLog 日志
24 0

热门文章

最新文章

相关产品

  • 云迁移中心