Files
rikako-note/spring/logback/logback.md
2024-08-05 00:22:58 +08:00

128 lines
5.7 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Logback
## Introduce
`logback-classic`模块需要classpath下存在`slf4j-api.jar`, `logback-core.jar`, `logback-classic.jar`
logback使用示例如下
```java
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld1 {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
logger.debug("Hello world.");
}
}
```
`HelloWorld1`类定义在`chapters.introduction`包下其引入了slf4j中的`Logger``LoggerFactory`类。
在上述示例中并没有引入任何logback的类在使用日志的大多数场景中只需要引入slf4j的api类即可。
## Logback Architecture
logback目前结构分为3个模块`logback-core``logback-classic``logback-access`
`logback-core`是其他两个模块的基础,`classic`模块拓展了`core`模块。`classic`模块实现了slf4j api因而在使用slf4j时可以在logback和其他日志系统之间轻松切换。而`access`模块和servlet容器做了集成可以通过http对日志进行访问。
### Logger, Appender, Layout
logback基于3个主要的类构成`Logger`, `Appender`, `Layout``Logger`类属于logback-classic模块Appender和Layout类则是属于logback-core模块。
#### Log Context
在logback-classic中每个logger都关联了一个`Log Context`log Context负责创建logger并且log context将创建的logger按照树状结构排列。
Logger都拥有名称其名称大小写敏感并遵循分层的命名规则
> 如果一个logger的名称其名称加上`.`后形成的字符串为另一个logger的前缀那么可称后一个logger是前一个logger的后代。如果一个logger和后代logger之间没有其他的logger那么可以称前一个logger是后一个logger的parent。
例如,名称为`"com.foo"`的logger是名称为`"com.foo.Bar"`的parent。
root logger是位于最顶层的logger其可以通过如下方式进行获取
```java
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
```
其他所有的logger也可以通过`getLogger`方法进行获取该方法接收logger name来作为参数`Logger`接口具有如下方法:
```java
package org.slf4j;
public interface Logger {
// Printing methods:
public void trace(String message);
public void debug(String message);
public void info(String message);
public void warn(String message);
public void error(String message);
}
```
#### 有效级别
logger都会被指定一个log levellevel可以是`TRACE, DEBUG, INFO, WARN, ERROR`中的一个,其定义在`ch.qos.logback.classic.Level`类中。如果指定logger没有被指定level那么其会从`离其最近并且被指定level的先祖logger`中继承level。
为了保证所有logger都可以继承levelroot logger一定会被指定log level。默认情况下level为`debug`
> log level顺序为
>
> `TRACE < DEBUG < INFO < WARN < ERROR`
#### 获取Logger
在通过`LoggerFactory.getLogger`获取logger对象时如果向方法传入相同的名称那么会获得相同的logger对象。
通常应在每个class中指定一个loggerlogger name为class的全类名。
#### Appender
在logback中允许将日志打印到多个目的地在logback中目的地被称为`Appender`。目前目的地可以是console、文件、remote socket server、数据库、JMS等。
对每个logger都可以关联不止一个Appender。
`addAppender`将会将Appender关联到指定的logger。每个被允许打印的log请求都会被发送到该logger关联的所有Appender中并且log请求还会被发送到树结构更高的Appender中。在logger结构中Appender是增量继承的后代logger会继承先祖logger的Appender。
如果为root logger指定一个console appender并且为L指定一个file appender那么对于L和L的后代logger打印日志的请求不仅会被发送到console还会被打印到文件中。
> 可以手动指定logger L增量继承appender的标志为false那么L和其所有后代logger都不会继承L先祖logger的appender。
>
> 默认情况下appender是否增量继承的标志默认值为true
#### Layout
如果想要指定日志打印的格式可以将Layout对象和logger相关联。`PatternLayout`可以通过c语言`printf`的格式来指定打印格式。
`PatternLayout`若指定conversion pattern为`%-4relative [%thread] %-5level %logger{32} - %msg%n`,其会按如下格式打印消息:
```
176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.
```
#### 参数化打印
可以通过如下形式来进行参数化打印
```java
Object entry = new SomeObject();
logger.debug("The entry is {}.", entry);
```
只有当前消息被评估应该打印时,才会通过消息模板来构造消息,将`{}`替换为entry的实际值。
## Logback Configuration
### logback配置顺序
1. 如果`logback.configurationFile`系统变量设置
2. 如果1步骤失败会尝试在classpath中寻找`logback-test.xml`
3. 如果2步骤失败会尝试在classpath中寻找`logback.xml`
### 通过xml形式配置logback
```xml
<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} -%kvp- %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
```