Spring Boot + Log4j2 日志框架配置 (Maven)

参考Spring Boot官方文档 日志部分

Spring Boot默认情况下,当使用"Starters" 使用Logback输出日志
, 还包括适当的Logback路由, 确保其他的日志框架(Java Util Logging, Commons Logging, Log4j, SLF4J)都能正常使用

Sping Boot文档的 26.5 Custom Log Configuration 章节,说明了自定义日志配置方法

多样的日志系统可以通过

  1. 添加适当的日志框架库到classpath
  2. 适当的配置配置文件加入到classpath的根目录 或者 其他的本地目录, 使用Spring配置 loggin.config 配置指定配置文件

依赖于开发者选择的日志框架. 这些对应的配置文件会被加载

日志框架 配置文件
Logback logback-spring.xmllogback-spring.groovylogback.xmllogback.groovy
Log4j2 log4j2-spring.xmllog4j2.xml
JDK(JAVA Util Logging) logging.properties

引入Log4j2日志框架

Log4j2为何物就不介绍了. Log4j2官网

配置的方案 在官方文档 77.2 Configure Log4j for Logging

1. Maven依赖配置

pom.xml中去掉Logback, 引入log4j2



    org.springframework.boot
    spring-boot-starter-web
    
        
            org.springframework.boot
            spring-boot-starter-logging
        
    



    org.springframework.boot
    spring-boot-starter-log4j2

2. 配置文件

2.1 log4j2.xml

使用xml格式配置文件, 无需添加额外的依赖库.

2.2 log4j2.yaml / log4j2.yml

使用 yaml/yml格式配置文件. 需要额外引入依赖库



    com.fasterxml.jackson.core
    jackson-databind



    com.fasterxml.jackson.dataformat
    jackson-dataformat-yaml

2.3 log4j2.json

使用 json 格式配置文件, 需要额外引入依赖库


    com.fasterxml.jackson.core
    jackson-databind

3. 修改spring boot配置

指定spring boot配置文件

application.yaml文件配置如下

logging:
  config: classpath:log4j2.xml

Log4j2日志配置

如需了解Log4j2详尽的配置, 可访问官方文档

概述

大概介绍一下Log4j2的基本信息

日志的Level分为:

  1. trace (追踪)
  2. debug (调试)
  3. info (信息)
  4. warn (警告)
  5. error (错误)
  6. fatal (严重错误)

这里介绍一下博主经常使用的一种日志方式 RollingFileAppender

以一个具体的配置为例



    
        /tmp/log4j2
    
    
        
            
                [%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
            
        
        
            
                [%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
            
            
                
            
        
    
    
        
            
            
        

        
            
        
    

1. Configuration 参数

  1. status: Level枚举型, 控制输出Log4j事件信息, 默认 error
  2. name: 配置名称
  3. strict: 是否使用严格的XML格式. 推荐使用, 规范开发者的配置编写, 不支持jsonp配置
  4. ... 其他几个配置可以参考官方文档

2. Properties

设置配置文件全局的参数变量. 用于减少自定义配置信息的重复编码.


    /tmp/log4j2

配置下文中, 可以使用 ${filepath} 来代替 /tmp/log4j2

3. Appenders

Log4j2提供了丰富的Appender

  1. AsyncAppender 设置appender异步方式输出日志
  2. CassandraAppender 输出至Cassandra存储
  3. ConsoleAppender 输出控制台
  4. FailoverAppender 设置appender错误重试
  5. FileAppender 输出至文件
  6. FlumeAppender 输出至Flume
  7. JDBCAppender 输出至JDBC连接的关系型数据库表
  8. JMS Appender 输出至消息服务
  9. JPAAppender 输出至使用JPA连接的关系行数据库
  10. HttpAppender 输出至Http Service
  11. KafkaAppender 输出至Kafka
  12. MemoryMappedFileAppender 输出至内存
  13. NoSQLAppender 输出至NoSQL数据库
  14. OutputStreamAppender File/Socket类型的Appender
  15. RandomAccessFileAppender 性能是FileAppder的0.2-2倍
  16. RollingFileAppender 输出至文件, 文件能按照规则打包文件
  17. RollingRandomAccessFileAppender 同上
  18. SMTPAppender 邮件形式输出
  19. SocketAppender socket方式发送日志

项目中比较常用的是 ConsoleAppender 和 RollingFileAppender.

接下来对上述的Appender配置参数的说明


    
    
    
    
        
        
            [%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
        
    

    
    
    
    
        
            [%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
        
        
            
            
            
            
        
    

3.2 日志输出规则 Layouts

Layout有多种格式输出

  1. CSV
  2. GELF
  3. HTML
  4. JSON
  5. Pattern
  6. ....

项目中一般使用Pattern 按行输出逐条信息, 配置如下:



    [%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n

% + char/word 代表一种输出的信息或者格式

时间 %d / %date

格式 输出
%d, %d{DEFAULT} 2012-11-02 14:34:02,781
%d{UNIX} 1351866842
%d{UNIX_MILLIS} 1351866842781
%d{yyyy-MM-dd HH:mm:ss,SSS} 2012-11-02 14:34:02,781

类 %c / %logger

输出调用的类名

%c{number} , 控制类型的长度

等级 %level

输出等级 TRACE, DEBUG, INFO, WARN, ERROR, FATAL

颜色格式 %highlight

%heighlight{xxx}

xxx将会带有颜色样式, 并且和Level相关, 一般用于debug调试信息使用

日志内容 %m / %msg / %message

可添加文本样式

换行 %n

根据操作系统的输出不同的换行标识符用户日志换行, 最好别使用 \n\r\n 等换行符号

其他还有很多标识符号, 参考 官方文档

4. Loggers

  1. 必须包含一个 Root 元素, 不设置 Root 元素, 将会默认使用类似如下的配置

    
  1. 配置其他开发者自定义的 Logger

    
    
    
    
        
        
        
    

    
        
    

使用Logger

以demo为例

package info.chiwm.log4j2.service;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 * @author [email protected]
 * @ClassName: Log4j2ServiceImpl
 * @Description:
 * @date 2018/1/4 上午11:10
 */

@Service
public class Log4j2ServiceImpl implements Log4j2Service {
    // 使用LogManager获取配置Logger
    private static Logger logger = LogManager.getLogger("fileLogger");

    @Override
    public void info(String msg) {

        // 输出日志
        // 特别注意 不要使用 `+` 去拼接信息, 这样在控制输出级别之后, 有些日志操作不会打印, 但是它去操作了新字符串创建, 使用 `{}` 去代替 `+`
        logger.info("info {}", msg);
    }

    @Override
    public void error() {
        logger.error("error");
    }

    @Override
    public void warn() {
        logger.warn("warn");
    }

    @Override
    public void debug() {
        logger.debug("debug");
    }

    @Override
    public void trace() {
        logger.trace("trace");
    }
}

总结

前面的配置步骤,配置,使用步骤,大概描述了Log4j2的使用.

 

http://blog.51cto.com/11931236/2058708

log4j2.x日志按日期分隔

log4j2.x的日志在性能上有很大的提升,也被标识为下一代的异步日志管理系统。
项目组在使用的时候,发现日志没有按照日期进行文件分割。于是亲自上log4j2.x的官网查看了部分文档。
按如下配置即可实现日志按日期进行分割:



  
        
    
          
        
        
          
            
              
        
    
      
    
      
      
    
  
  
    
    
        
          
          
    
  

--------------------- 
作者:业余草 
来源:CSDN 
原文:https://blog.csdn.net/xmtblog/article/details/49019711?utm_source=copy 

 

  
  
      
      
          
              
              
          
          
          
           
              
              
              
             
 
                  
                  
                  
              
              
          
           
          
                       
                       
              
              
          
      
      
        
        
            
          
        
        
  


Spring boot 日志分档基于log4j2.yaml 配置文件

Why is Log4j2?

优化 说明
执行速度 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的并发支持,并且以最低级别执行锁定。

日志由logback替换为log4j2

去除

        
            org.springframework.boot
            spring-boot-starter-web
            
                
                    org.springframework.boot
                    spring-boot-starter-logging
                
            
        

引用

        
            org.springframework.boot
            spring-boot-starter-log4j2
        
        
        
            com.fasterxml.jackson.dataformat
            jackson-dataformat-yaml
        

在所有项目中引用到logback的包都去除

            
                
                    ch.qos.logback
                    logback-classic
                
            

spring boot 默认配置文件参数设置

  设置日志的位置,默认是放在resource根目录下面的

logging.config=classpath:log4j2.yml

log4j2.yml



# 共有8个级别,按照从低到高为:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF。

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

日志获取工具类

package com.lck.demo.endeavour.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 本地日志参考类
 *
 * @author ckli01
 * @date 2018/5/8
 */
public class LogUtils {


    /**
     * 获取业务日志logger
     *
     * @return
     */
    public static Logger getBussinessLogger() {
        return LoggerFactory.getLogger(LogEnum.BUSSINESS.getCategory());
    }

    /**
     * 获取平台日志logger
     *
     * @return
     */
    public static Logger getPlatformLogger() {
        return LoggerFactory.getLogger(LogEnum.PLATFORM.getCategory());
    }

    /**
     * 获取数据库日志logger
     *
     * @return
     */
    public static Logger getDBLogger() {
        return LoggerFactory.getLogger(LogEnum.DB.getCategory());
    }


    /**
     * 获取异常日志logger
     *
     * @return
     */
    public static Logger getExceptionLogger() {
        return LoggerFactory.getLogger(LogEnum.EXCEPTION.getCategory());
    }


}

枚举类:

package com.lck.demo.endeavour.util;

/**
 * 本地日志枚举
 *
 * @author ckli01
 * @date 2018/5/8
 */
public enum  LogEnum {


    BUSSINESS("bussiness"),

    PLATFORM("platform"),

    DB("db"),

    EXCEPTION("exception"),

    ;


    private String category;


    LogEnum(String category) {
        this.category = category;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }
}



作者:ClineChen
链接:https://www.jianshu.com/p/8785e9510184
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

 

你可能感兴趣的:(log)