1.是什么?
log4j已成为大型系统必不可少的一部分,log4j可以很方便的帮助我们在程序的任何位置输出所要打印的信息,便于我们对系统在调试阶段和正式运行阶段对问题分析和定位。
2.日志级别
1.日志级从低到高:debug
,info
,warn
,error
, 依次升高,性能越高;
2.影响输出性能条件:
- 输出到文件系统 > 控制台
- SimpleLayout > PatternLayout,不带格式化的直接输出更快;
- 日志级别越高,内容输出越少,应用受日志打印影响越少,性能越高;
根据不同场景选择不同的日志级别,一般按环境划分(开发,测试,生产),开发需要足够的调试日志信息,线上只需要一些关键的warn/更高级别的日志,避免日志过多或影响性能。
3.日志门面
- Simple Logging Facade for Java(SLF4J)用作各种日志框架(例如 java.util.logging,logback,log4j)的简单外观或抽象,允许最终用户在部署时插入所需的日志框架;
总的来说,slf4j就是众多日志接口的集合(接口定义),不负责具体的日志实现,只在编译时寻找合适的日志系统进行绑定;
4.外观模式应用
外观模式:外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面;
SLF4j的logger需要直接或间接指向实际依赖的日志系统的logger,通过实现LoggerFactoryBinder接口完成日志实现的绑定;
5.使用规范
【强制】应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);
保证不会创建多个日志系统的logger,会选择绑定其中一个(根据配置文件,无配置文件则根据pom引入顺序)
lombok slf4j
6.log.info做了什么
1.找到log.info()
@Override
public void info(final Marker marker, final String s, final Object o, final Object o1) {
logger.logIfEnabled(FQCN, Level.INFO, getMarker(marker), s, o, o1);
}
2.进一步查看:
private void logMessageSafely(final String fqcn, final Level level, final Marker marker, final Message msg,
final Throwable throwable) {
try {
logMessage(fqcn, level, marker, msg, throwable);
} finally {
// LOG4J2-1583 prevent scrambled logs when logging calls are nested (logging in toString())
ReusableMessageFactory.release(msg);
}
}
3.从日志中读取要输出到appender的策略(从log4j2.xml
中解析),执行log操作:
@Override
public void logMessage(final String fqcn, final Level level, final Marker marker, final Message message,
final Throwable t) {
final Message msg = message == null ? new SimpleMessage(Strings.EMPTY) : message;
final ReliabilityStrategy strategy = privateConfig.loggerConfig.getReliabilityStrategy();
strategy.log(this, getName(), fqcn, marker, level