java日志:slf4j
一、设计模式之门面模式(facade)
1. 概念:外部与子系统的通信,必须通过统一的外观对象(facade)进行,使得子系统更易于使用
2. 模式图
3. 核心点:
a. 知道所有子角色的功能和责任
b. 将客户端发来的请求,委派到子系统中,门面对象没有实际的业务逻辑
c. 不参与子系统内业务逻辑的实现
二、slf4j概述
1. slf4j是门面模式的典型应用,因为一个系统中可能有其他jar包,使用了logback, log4j, slf4j等不同的日志系统,需要引入一个适配层去决定使用哪种日志系统
2. slf4j只是一个日志标准,并不是日志系统的具体实现:提供日志接口、提供获取具体日志对象的方法
3. slf4j的默认实现:NOPLogger,但是这个实现都是空方法,并不会打印日志;需要使用具体的实现,例如logback,如果没有具体实现,会报错
4. slf4j的具体实现:slf4j-simple, logback, slf4j-log4j12,直接引入对应的jar包即可
三、应用:使用slf4j+logback
1. 添加依赖
<dependency> // slf4j <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <dependency> // logback实现slf4j <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
2. 添加logback配置文件,可以指定控制台和文件进行日志输出
<?xml version="1.0" encoding="UTF-8"?> <configuration> <property name="LOG_DIR" value="logs"/> <property name="COMMON_PATTERN" value="%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{0} - %msg%n"/> <!-- - - - - - - - appender - - - - - - - --> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <pattern>${COMMON_PATTERN}</pattern> </layout> </appender> <appender name="myproject" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>logs/myproject.log</File> <encoder> <pattern>${COMMON_PATTERN}</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/myproject.%d{yyyy-MM-dd}.log.zip</FileNamePattern> <MaxHistory>7</MaxHistory> <CleanHistoryOnStart>true</CleanHistoryOnStart> </rollingPolicy> </appender> <appender name="error-log" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>logs/error.log</File> <encoder> <pattern>${COMMON_PATTERN}</pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern>logs/error.%d{yyyy-MM-dd}.log.zip</FileNamePattern> <MaxHistory>7</MaxHistory> <CleanHistoryOnStart>true</CleanHistoryOnStart> </rollingPolicy> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> </appender> <appender name="trace-async-appender" class="ch.qos.logback.classic.AsyncAppender"> <!-- 异步打印日志,更改默认的队列的深度,该值会影响性能.默认值为256 --> <queueSize>512</queueSize> <!-- 添加附加的appender,最多只能添加一个 --> <appender-ref ref="myproject"/> </appender> <logger name="abc" level="TRACE" additivity="false"> <appender-ref ref="trace-async-appender"/> <appender-ref ref="console"/> </logger> <root level="WARN"> <appender-ref ref="console"/> <appender-ref ref="myproject"/> <appender-ref ref="error-log"/> </root> </configuration>
3. 在代码中使用
Logger logger = LoggerFactory.getLogger(Object.class); logger.info("info"); logger.warn("warn");
四、slf4j实现原理
1. Logger logger = LoggerFactory.getLogger(Object.class); 根据日志工厂获得具体的日志类
2. getLogger的时候会去classpath下找STATIC_LOGGER_BINDER_PATH,即”org/slf4j/impl/StaticLoggerBinder.class”,每一个日志实现的jar包里都有这个类
3. 存在多个日志实现,会有警告产生,并选择其中一个实现