(粗糙选译。。)html
Joran是logback所依赖的配置框架。java
观察代表,在一个应用程序中,日志代码大概占4%左右。node
因此即使是一个几千行。。几万行的程序也有成百上千的日志语句,鉴于它们的数量,咱们须要工具来管理这些日志语句。logback既能够经过编程方式配置,也能够经过脚本配置(XML或Groovy 格式)。顺便说一下,现有的log4j用户可使用PropertiesTranslator 应用程序将log4j.properties转换为logback.xml。apache
让咱们从讨论logback尝试配置自身的初始化步骤开始:编程
com.qos.logback.classic.spi.Configurator接口
的实现。它的内容应该指定所需Configurator实现的彻底限定类名。BasicConfigurator
自动配置本身,这将致使日志输出定向到控制台。<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.sample.logback</groupId> <artifactId>test-logback</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- -source 1.5 中不支持 try-with-resources--> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-core --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <!--Failed to load class "org.slf4j.impl.StaticLoggerBinder".--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.21</version> </dependency> </dependencies> </project>
BasicConfigurator是logback默认的一个最小可用的配置。试了下文档里的例子程序,在main函数里跑,debug信息莫名奇妙输不出来(只输出info的),但在junit里跑却又能够。。
api
和没有xml文件时的默认配置等价的最小可用xml配置:oracle
<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
启用“观察logback内部状态模式”(若是logback出现内部错误则不启用也会自动输出到控制台):app
// assume SLF4J is bound to logback in the current environment
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
// print logback's internal status
StatusPrinter.print(lc);
启用“观察logback内部状态模式”一般对诊断logback问题大有帮助。所以,强烈建议将其视为第一求助办法。(通常状况都是推荐启用的。)xml启用“观察logback内部状态模式”:框架
<configuration debug="true"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder --> <encoder> <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
等价写法:maven
<configuration> <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" /> ... the rest of the configuration file </configuration>
30秒(默认单位是毫秒)扫描一次,若是文件改变就自动从新配置:
<configuration scan="true" scanPeriod="30 seconds" > ... </configuration>
在编辑xml的时候很容易出错,因此感受不是很好用。
略
经过网页来查看logback的内部状态信息。
略
略
略
Example1- 关于logger、root、appender元素的一些基本知识
<configuration debug="true"> <!--一个可选的元素,便于区分不一样程序的输出--> <contextName>myapp</contextName> <!--配置appender元素: 一、name和class是必要的 二、一个appender能够包含零到多个layout元素 三、一个appender能够包含零到多个encoder元素 四、一个appender能够包含零到多个filter元素 五、除了这三个公共元素以外,<appender>元素能够包含与appender类的JavaBean属性相对应的任意数量的元素。 --> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>myApp.log</file> <encoder> <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> </encoder> </appender> <!-- 配置logger元素: 一、name是必要的 二、level是可选的,没有就继承最近的,具备“赋予等级”的祖先的“赋予等级”。 TRACE, DEBUG, INFO, WARN, ERROR, ALL, OFF, INHERITED, NULL(填最后两个 等价于省略level,而且最后两个效果等价) 三、additivity是可选的,默认是true 四、一个logger能够包含零到多个appender-ref元素 --> <logger name="org.sample.logback.Foo" level="OFF" additivity="true" /> <logger name="org.sample.logback.LogbackTest" level="INFO" additivity="false"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </logger> <!-- 配置root元素: 一、它不支持除了level外的任何其它属性 二、appender-ref元素和普通logger同样 --> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
Example2- 变量定义初步
<configuration debug="true"> <!-- 方法一,简单变量替换 --> <property name="USER_HOME" value="log_files" /> <!-- 方法二,采用系统属性(System property)达到一样效果--> <!-- java -DUSER_HOME="log_files" MyApp2 --> <!--方法三杠一,经过文件导入变量,当变量多的时候这样比较方便--> <property file="src/main/java/variables1.properties" /> <!--文件内容USER_HOME=log_files--> <!-- 方法三杠二,等效三杆一,不过这个时候资源在类路径里 --> <property resource="resource1.properties" /> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${USER_HOME}/myApp.log</file> <encoder> <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> </encoder> </appender> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default --> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <logger name="org.sample.logback.LogbackTest" level="INFO" additivity="false"> <appender-ref ref="STDOUT" /> <appender-ref ref="FILE" /> </logger> <root level="debug"> <appender-ref ref="STDOUT" /> </root> </configuration>
logback彻底支持变量嵌套。变量的名称、默认值和值定义均可以引用其余变量:
USER_HOME=/home/sebastien
fileName=myApp.log
destination=${USER_HOME}/${fileName}
再好比${${userid}.password}、${id:-${userid}}。。
Example3- 变量做用域
<configuration> <!-- LOCAL SCOPE 默认的做用域。变量生命周期:在配置文件中定 义的位置开始直到配置文件被解析/执行完成。意味 着每次解析配置文件都将建立一个新的这个变量。 CONTEXT SCOPE 插入到上下文(context),直到context被清除。 一旦定义,CONTEXT SCOPE中的属性就是context的 一部分。所以,它在全部日志事件中均可用,包括 经过序列化发送到远程主机的日志事件。 SYSTEM SCOPE 带有SYSTEM做用域的属性被插入到JVM的系统属性中, 而且持续到JVM清除为止。 --> <!-- 在替换配置文件中的变量时,变量的查找 顺序是LOCAL>CONTEXT>SYSTEM,最后是操做 系统环境变量 --> <property scope="context" name="nodeId" value="firstNode" /> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <!-- 用":-"定义默认值 --> <file>log_files/${nodeId:-secondNode}/myApp.log</file> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="FILE" /> </root> </configuration>
Example4- HOSTNAME和CONTEXT_NAME是默认的两个变量(好像是惰性初始化的)
<configuration> <property scope="context" name="nodeId" value="firstNode" /> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>log_files/${HOSTNAME}/${CONTEXT_NAME}/myApp.log</file> <!--C:\Users\mdzz\Desktop\test-mvn\testlogback\log_files\LAPTOP-QGECNCGO\default\myApp.log--> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="debug"> <appender-ref ref="FILE" /> </root> </configuration>
Generate