参考Spring Boot官方文档 日志部分
Spring Boot默认情况下,当使用"Starters" 使用Logback输出日志
, 还包括适当的Logback路由, 确保其他的日志框架(Java Util Logging, Commons Logging, Log4j, SLF4J)都能正常使用
Sping Boot文档的 26.5 Custom Log Configuration 章节,说明了自定义日志配置方法
多样的日志系统可以通过
loggin.config
配置指定配置文件依赖于开发者选择的日志框架. 这些对应的配置文件会被加载
日志框架 | 配置文件 |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml , logback.groovy |
Log4j2 | log4j2-spring.xml , log4j2.xml |
JDK(JAVA Util Logging) | logging.properties |
Log4j2为何物就不介绍了. Log4j2官网
配置的方案 在官方文档 77.2 Configure Log4j for Logging
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.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
指定spring boot配置文件
application.yaml
文件配置如下
logging:
config: classpath:log4j2.xml
如需了解Log4j2详尽的配置, 可访问官方文档
大概介绍一下Log4j2的基本信息
日志的Level分为:
这里介绍一下博主经常使用的一种日志方式 RollingFileAppender
以一个具体的配置为例
/tmp/log4j2
[%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
[%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
status
: Level枚举型, 控制输出Log4j事件信息, 默认 errorname
: 配置名称strict
: 是否使用严格的XML格式. 推荐使用, 规范开发者的配置编写, 不支持jsonp配置设置配置文件全局的参数变量. 用于减少自定义配置信息的重复编码.
/tmp/log4j2
配置下文中, 可以使用 ${filepath}
来代替 /tmp/log4j2
Log4j2提供了丰富的Appender
项目中比较常用的是 ConsoleAppender
和 RollingFileAppender
.
接下来对上述的Appender配置参数的说明
[%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
[%d] - [%c] - [%highlight{%level}] - [%method] - [%t] - %msg%n
3.2 日志输出规则 Layouts
Layout有多种格式输出
项目中一般使用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
等换行符号
其他还有很多标识符号, 参考 官方文档
Root
元素, 不设置 Root
元素, 将会默认使用类似如下的配置
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的官网查看了部分文档。
按如下配置即可实现日志按日期进行分割:
---------------------
作者:业余草
来源:CSDN
原文:https://blog.csdn.net/xmtblog/article/details/49019711?utm_source=copy
优化 | 说明 |
---|---|
执行速度 | 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的并发支持,并且以最低级别执行锁定。 |
去除
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
设置日志的位置,默认是放在resource根目录下面的
logging.config=classpath: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
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。