springboo日志t详细介绍

序:

诞生简介

Java知名的日志有很多,比如:JUL、Log4j、JCL、SLF4J、Logback、Log4j2,那么这些日志框架之间有着怎样的关系?诞生的原因又是解决什么问题?下面一起来看。

简介说明
JULJava有自己的日志框架JUL(Java Util Logging)在java.util.logging下,因为对开发者不友好,使用成本太高和日志级别分类不清晰的问题,所有很少有开发者用。
Log4j因为JUL的缺陷问题,这就给了Log4j机会,所有Log4j一经推出就迅速风靡全球。
JCLJCL是Jakarta Commons-Logging的缩写,Jakarta在这里指的是一个组织,而不是印度的首都雅加达,Jakarta,一个早期的Apache开源项目,用于管理各个Java子项目,诸如Tomcat, Ant, Maven, Struts, JMeter, Velocity, JMeter, Commons等。2011年12月,在所有子项目都被迁移为独立项目后,Jakarta名称就不再使用了。JCL诞生的初衷是因为Java自身的一些包用了JUL,而Log4j用户使用的有很多,那么JCL就是提供一套API来实现不同Logger之间的切换。
SLF4JSLF4J(Simple Logging Facade For Java)简单日志门面,和JCL功能类似,但JCL有一个致命的缺点就是算法复杂,出现问题难以排除,而SLF4J的诞生就是为了解决JCL的缺点。值得一提的是SLF4J的作者就是Log4j的作者。
LogbackLogback是Log4j的作者的另一个开源日志组件,与Log4j相比,Logback重新了内核,使它的性能提升了很多,大约是Log4j的10倍,同时占用更小的内存,并且完整的实现了SLF4J API是你可以很方便的切换日志框架
Log4j2Log4j2有着和Logback相同的功能,但又有自己单用的功能,比如:插件式结构、配置文件优化、异步日志等。 Log4j2是Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些固有问题。从GitHub的更新日志来看, Logback已经有半年没有更新了, 而作为知名组织的Apache下的Log4j2的更新却是非常活跃的Log4j 1.x 于2015年8月停止维护更新了

优缺点

优化说明
执行速度Log4j 2.x 相对于 Log4j 1.x 和 Logback来说,具有更快的执行速度。一方面由于 重写了内部的实现,在某些特定的场景上面,甚至可以比之前的速度快上10倍。比如内部的消息队列采用了ArrayBlockingQueue,相对于原始的ArrayList和锁操作来说,管程类的消息队列拥有更好地性能。同时所需的内存更加少。这是因为Log4j 2.x 采用占位符的形式打印日志(类似于Slf4j门面日志的形式),会先判断一下日志的等级,然后再拼接要打印的内容。另一方面由于Log4j 2.x 充分利用Java 5的并发特性(主要是使用了一些concurrent包下锁),使得性能得到一定的改善,而Log4j 1.x和Logback很多地方还是用的重锁。
异步性能Asynchronous Loggers是Log4j2新增的日志器,异步日志器在其内部实现采用了LMAX Disruptor(一个无锁的线程间通信库)技术,Disruptor主要通过环形数组结构、元素位置定位和精巧的无锁设计(CAS)实现了在高并发情形下的高性能。而且Log4j 2.x中Asynchronous Appenders作为Asynchronous Loggers工作的一部分,效果进行了增强。每次写入磁盘时,都会进行flush操作,效果和配置“immediateFlush=true”一样。该异步Appender内部采用ArrayBlockingQueue的方式。RandomAccessFileAppender采用ByteBuffer+RandomAccessFile替代了BufferedOutputStream,官方给出的测试数据是它将速度提升了20-200%。
自动加载配置文件Log4j 2.x 和Logback都新增了自动加载日志配置文件的功能,又与Logback不同,配置发生改变时不会丢失任何日志事件。当Log4j 2.x中配置发生改变时,如果还有日志事件尚未处理,Log4j 2会继续处理,当处理完成后,Logger会重新指向新配置的LoggerConfig对象,并且删除无用的对象。
死锁问题的解决在Log4j 1.x中同步写日志的时候,在高并发情况下出现死锁导致cpu使用率异常飙升。其中的原因是当一个进程写日志的时候需要获取到Logger和Appender。org.apache.log4j.Logger类继承于org.apache.log4j.Category、Appender继承于org.apache.log4j.AppenderSkeleton。通过Log4j 1.x中Category源码和Appender源码可以知道,当多线程并发时,可能会因为相互持有Logger和Appender发生死锁。 而在log4j 2.x中充分利用Java5的并发支持,并且以最低级别执行锁定。

springboot日志介绍

1、默认行为

(1)springboot默认帮我们配置好了日志,在类中可以直接使用。其默认使用logback作为应用日志框架,级别为info;
(2)默认情况SpringBoot将日志输出到控制台,不会写到日志文件,如果要编写除了控制台输出之外的日志文件,则需要在配置文件中配置logging.file或者loggin.path属性值,file和path是不能同时配置的,如果同时配置path不会生效。
(3)默认情况下,日志文件的大小达到10M时会切分一次,产生新的日志文件。
(4)Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置(如使用logback-spring.xml,而不是logback.xml),命名为logback-spring.xml的日志配置文件,spring boot可以为它添加一些spring boot特有的配置项。
(5)由于日志服务一般都在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

2、自定义日志

(1)若想完全掌控日志配置,可在springboot配置文件中指定日志配置文件(日志配置文件名可自定义)

	logging.config=classpath:logging-config.xml
	    或者
	    logging:
	        config: classpath:logging-config.xml

3、不适用xml,直接使用yml或者properties配置

yml 配置:

logging:
  level: #日志级别 ,可设置相应包对应日志级别
    # 指定包自定义日志级别
    com:
      lyu: info
  #file和path是不能同时配置的,如果同时配置path不会生效
  path: /var/log #设置目录,会在该目录下创建spring.log文件,并写入日志内容,如:logging.path=/var/log
  file: my.log #设置文件,可以是绝对路径,如:e:\\demo\\demo.log ;也可以是相对路径(项目的当前路径)。如:logging.file=my.log
  pattern:
    file: '%d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n'
    console: '%d{yyyy-MMM-dd HH:mm:ss.SSS} %-5level [%thread] %logger{15} - %msg%n'
    dateformat: yy-MM-dd HH:mm:ss.sss #时间格式指定

properties 配置:

#可对包进行自定义日志级别控制
logging.level.com.lyu=debug

#logging.path 和 logging.path 是冲突设置 ,两者都设置时只有 logging.path 起作用
# 在当前磁盘路径下创建spring文件夹和里面的log文件夹;使用spring.log 作为默认文件
logging.path=D:/log1Demo

#指定文件名,就在项目下生产springboot.log日志
#logging.file=springboot.log

#设置日志文件最大保存时间
logging.file.max-history=30

#设置日志文件大小
logging.file.max-size=10MB

# 指定控制台输出的日志格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} -%msg%n

# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} === %msg%n

#定义渲染不同级别日志的格式。默认%5p
logging.pattern.level=%5p

#用于指定日志配置文件
#logging.config=classpath:logback-spring.yml

#记录异常时使用的转换字。
logging.exception-conversion-word=%wEx

logging.pattern.dateformat=yy-MM-dd HH:mm:ss.sss

4、使用xml配置

(1)简单示例

<configuration>
    <!-- 日志文件名称-->
  <property name="LOG_PREFIX" value="spring-boot-logback" />

  <!-- 日志文件编码-->
  <property name="LOG_CHARSET" value="UTF-8" />

  <!-- 日志文件路径+日期-->
  <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" />

  <!--对日志进行格式化-->
  <property name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/>

  <!--文件大小,默认10MB-->
  <property name="MAX_FILE_SIZE" value="50MB" />

  <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
  <property name="MAX_HISTORY" value="10"/>

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 输出的日志内容格式化-->
    <layout class="ch.qos.logback.classic.PatternLayout">
      <pattern>${LOG_MSG}</pattern>
    </layout>
    </appender>

    <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件路径,日志文件名称-->
        <File>${LOG_HOME}/all_${LOG_PREFIX}.log</File>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

        <!--日志文件路径,新的 ALL 日志文件名称,“ i ” 是个变量 -->
            <FileNamePattern>${LOG_DIR}/all_${LOG_PREFIX}%i.log</FileNamePattern>

        <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
        <MaxHistory>${MAX_HISTORY}</MaxHistory>

            <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>

        <!-- 输出的日志内容格式化-->
        <!--<layout class="ch.qos.logback.classic.PatternLayout">-->
        <!--  <pattern>${LOG_MSG}</pattern>-->
        <!--</layout>-->

        <!--输出格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <!--设置编码-->
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <root level="${LOG_ROOT_LEVEL}">

    <!-- FILE_ALL 日志输出添加到 控制台 -->
    <appender-ref ref="CONSOLE"/>

    <!-- FILE_ERROR 日志输出添加到 logger -->
    <appender-ref ref="FILE_ALL"/>
  </root>

</configuration>

(2)节点介绍

根节点:

configuration

root节点:

是必选节点,用来指定最基础的日志输出级别,只有一个level属性,用于设置打印级别。
节点可以包含0或者多个节点,将添加进来。
等级从低到高分别是TRACE < DEBUG < INFO < WARN < ERROR

级别作用
Trace是追踪,就是程序推进以下,你就可以写个trace输出,所以trace应该会特别多,不过没关系,我们可以设置最低日志级别不让他输出.
Debug指出细粒度信息事件对调试应用程序是非常有帮助的.
Info消息在粗粒度级别上突出强调应用程序的运行过程.
Warn输出警告及warn以下级别的日志.
Error输出错误信息日志.
OFF表示关闭全部日志
ALL表示开启全部日志。
示例
	<root level="debug">
      	<appender-ref ref="console" />
      	<appender-ref ref="file" />
    </root>
property节点:

用于定义变量,有name和value两个属性,可以通过${}来使用变量

appender节点:

appender 用来格式化日志输出的节点,这个最重要。有两个属性:
name:本节点的名称
class:指定输出策略,通常有两种,控制台输出和文件输出
appender子节点介绍
File节点:指定日志文件路径和名称
rollingPolicy节点:设置滚动策略
layout节点:输出的日志内容格式化
encoder节点:输出的日志内容格式化

logger节点:

此节点用来设置一个包或具体的某一个类的日志打印级别、以及指定
name: 必须。用来指定受此 loger 约束的某个包或者某个具体的类
level:可选。设置打印级别。默认为 root 的级别。
addtivity: 可选。是否向上级 loger(也就是 root 节点)传递打印信息。默认为 true。

示例:
	   1.不指定级别,不指定 appender
       <!-- 控制com.example.service下类的打印,使用root的level和appender -->
       <logger name="com.example.service"/>

       2.指定级别,不指定 appender
       <!-- 控制com.example.service下类的打印,使用root的appender打印warn级别日志 -->
       <logger name="com.example.service" level="WARN"/>

       3.指定级别,指定 appender
       <!-- 控制com.example.service下类的打印,使用console打印warn级别日志 -->
       <!-- 设置addtivity是因为这里已经指定了appender,如果再向上传递就会被root下的appender再次打印 -->
       <logger name="com.example.service" level="WARN" addtivity="false">
           <appender-ref ref="console">
       </logger>
多环境日志输出:

通过设置文件名为-spring 结尾,可分环境配置 logger,示例如下:

        <!-- 测试环境+开发环境. 多个使用逗号隔开. -->
        <springProfile name="test,dev">
            <logger name="com.example.demo.controller" level="DEBUG" additivity="false">
                <appender-ref ref="console"/>
            </logger>
        </springProfile>
        <!-- 生产环境. -->
        <springProfile name="prod">
            <logger name="com.example.demo" level="INFO" additivity="false">
                <appender-ref ref="timeFileOutput"/>
            </logger>
        </springProfile>

(3)日志格式化规则

encoder表示对日志进行编码:

%d{HH: mm:ss.SSS}——日志输出时间
%thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用
%-5level——日志级别,并且使用5个字符靠左对齐
%logger{36}——日志输出者的名字
%msg——日志消息
%n——平台的换行符

5、使用log4j2代替默认日志

(1)排查自身日志包

		<!-- 排除自身默认日志(在spring-boot-starter-相关jar中进行排除) -->
		<exclusions>
			<exclusion>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-starter-logging</artifactId>
			</exclusion>
		</exclusions>

(2)引入使用的包

		<!-- 配置 log4j2 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
        </dependency>

        <!-- 加上这个才能辨认到log4j2.yml文件 -->
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-yaml</artifactId>
        </dependency>

(3)sringboot配置文件指定
根据不同配置文件属性,选择使用

		# properties配置文件
		logging.config=classpath:log4j2.yml
        # yml配置文件
        logging:
          config: classpath:log4j2.yml

(4)引入log4j2日志配置文件

实例如下:

1. xml 模式配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
      <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
          <PatternLayout charset="UTF-8" pattern="[%-5p] %d %c - %m%n" />
        </Console>

        <File name="File" fileName="D:\\mylog.log">
          <PatternLayout pattern="%m%n" />
        </File>
      </Appenders>

      <Loggers>
        <root level="info">
          <AppenderRef ref="CONSOLE" />
          <AppenderRef ref="File" />
        </root>
      </Loggers>
</configuration>

2. yml 配置模式

Configuration:
  status: warn
  monitorInterval: 30

  Properties: # 定义全局变量
    Property: # 缺省配置(用于开发环境)。其他环境需要在VM参数中指定,如下:
      #测试:-Dlog.level.console=warn -Dlog.level.xjj=trace
      #生产:-Dlog.level.console=warn -Dlog.level.xjj=info
      - name: log.level.console
        value: info
      - name: log.path
        value: log
      - name: project.name
        value: endeavour
      - name: log.pattern
        value: "%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p ${PID:-} [%15.15t] %-30.30C{1.} : %m%n"

  Appenders:
    Console:  #输出到控制台
      name: CONSOLE
      target: SYSTEM_OUT
      PatternLayout:
        pattern: ${log.pattern}
    #   启动日志
    RollingFile:
      - name: ROLLING_FILE
        fileName: ${log.path}/${project.name}.log
        filePattern: "${log.path}/historyRunLog/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
        PatternLayout:
          pattern: ${log.pattern}
        Filters:
          #        一定要先去除不接受的日志级别,然后获取需要接受的日志级别
          ThresholdFilter:
            - level: error
              onMatch: DENY
              onMismatch: NEUTRAL
            - level: info
              onMatch: ACCEPT
              onMismatch: DENY
        Policies:
          TimeBasedTriggeringPolicy:  # 按天分类
            modulate: true
            interval: 1
        DefaultRolloverStrategy:     # 文件最多100个
          max: 100
      #   平台日志
      - name: PLATFORM_ROLLING_FILE
        ignoreExceptions: false
        fileName: ${log.path}/platform/${project.name}_platform.log
        filePattern: "${log.path}/platform/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
        PatternLayout:
          pattern: ${log.pattern}
        Policies:
          TimeBasedTriggeringPolicy:  # 按天分类
            modulate: true
            interval: 1
        DefaultRolloverStrategy:     # 文件最多100个
          max: 100
      #   业务日志
      - name: BUSSINESS_ROLLING_FILE
        ignoreExceptions: false
        fileName: ${log.path}/bussiness/${project.name}_bussiness.log
        filePattern: "${log.path}/bussiness/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
        PatternLayout:
          pattern: ${log.pattern}
        Policies:
          TimeBasedTriggeringPolicy:  # 按天分类
            modulate: true
            interval: 1
        DefaultRolloverStrategy:     # 文件最多100个
          max: 100
      #   错误日志
      - name: EXCEPTION_ROLLING_FILE
        ignoreExceptions: false
        fileName: ${log.path}/exception/${project.name}_exception.log
        filePattern: "${log.path}/exception/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
        ThresholdFilter:
          level: error
          onMatch: ACCEPT
          onMismatch: DENY
        PatternLayout:
          pattern: ${log.pattern}
        Policies:
          TimeBasedTriggeringPolicy:  # 按天分类
            modulate: true
            interval: 1
        DefaultRolloverStrategy:     # 文件最多100个
          max: 100
      #   DB 日志
      - name: DB_ROLLING_FILE
        ignoreExceptions: false
        fileName: ${log.path}/db/${project.name}_db.log
        filePattern: "${log.path}/db/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.log.gz"
        PatternLayout:
          pattern: ${log.pattern}
        Policies:
          TimeBasedTriggeringPolicy:  # 按天分类
            modulate: true
            interval: 1
        DefaultRolloverStrategy:     # 文件最多100个
          max: 100


  Loggers:
    Root:
      level: info
      AppenderRef:
        - ref: CONSOLE
        - ref: ROLLING_FILE
        - ref: EXCEPTION_ROLLING_FILE
    Logger:
      - name: platform
        level: info
        additivity: false
        AppenderRef:
          - ref: CONSOLE
          - ref: PLATFORM_ROLLING_FILE

      - name: bussiness
        level: info
        additivity: false
        AppenderRef:
          - ref: BUSSINESS_ROLLING_FILE

      - name: exception
        level: debug
        additivity: true
        AppenderRef:
          - ref: EXCEPTION_ROLLING_FILE

      - name: db
        level: info
        additivity: false
        AppenderRef:
          - ref: DB_ROLLING_FILE


#    监听具体包下面的日志
#    Logger: # 为com.xjj包配置特殊的Log级别,方便调试
#      - name: com.xjj
#        additivity: false
#        level: ${sys:log.level.xjj}
#        AppenderRef:
#          - ref: CONSOLE
#          - ref: ROLLING_FILE

参考:

日志配置文件示例
参考链接1
参考链接2
参考链接3
参考链接4
来源于网络 如有侵权请联系删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值