refer
1-sbt-logging
1-1 Intro
1)-约定 > 配置
默认的配置基本够用.
- 日期格式: 包含日期时间、日志级别、进程ID、应用名称、线程名、日志来源和消息内容 ;
- 日志级别: 默认提供的是,
ERROR,WARN,INFO, 使用--trace开启TRACE, 使用--debug可以开启DEBUG级别 ;- 没有
FATAL级别的说法,会自动映射到ERROR;
- 没有
- 彩色控制: 需要终端支持
ANSI, 可以通过spring.output.ansi.enabled来控制 ;
2)-这个多框架的抽象是比较好的
- 基本能力的抽象:
- Log Format
- Console Output
- File Output
- File rotation
- Log Levels
- Log Groups
- Using a Log Shutdown Hook
- Custom Log Configuration
- 基于扩展的封装
- Logback-Extensions
- Profile-Specific Configuration
- Env Properties
- Log4j2 Extensions
- Profile-Specific Configuration
- Env
- Log4j2 System Properties
- Profile-Specific Configuration
- Logback-Extensions
1-2 Default is logback
首先 日志系统集成的源码是在 LoggingApplicationListener 中.
流程如下:
graph TD A[应用启动] --> B{系统属性中有指定日志系统?} B -->|是| C[使用指定的日志系统] B -->|否| D{遍历LoggingSystemFactory} D -->|找到合适的| E[创建对应的LoggingSystem] D -->|未找到| F[抛出异常] E --> G[初始化日志系统] C --> G
源码时序图
sequenceDiagram participant App as App participant LAL as LoggingAppListener participant LS as LoggingSystem participant LSF as LoggingSystemFactory participant LBS as LogbackLoggingSystem App->>LAL: ApplicationStartingEvent Note over LAL,LS: onApplicationStartingEvent LAL->>LS: get(classLoader) LS->>LSF: getLoggingSystem(classLoader) alt System property specified LS->>LS: Create specified LoggingSystem else No system property LSF->>LBS: new LogbackLoggingSystem LBS-->>LSF: Return instance end LSF-->>LS: Return LoggingSystem LS-->>LAL: Return LoggingSystem LAL->>LS: beforeInitialize()
核心代码就是 ClassUtils 判断类是否存在.
@Order(Ordered.LOWEST_PRECEDENCE)
public static class Factory implements LoggingSystemFactory {
private static final boolean PRESENT = ClassUtils.isPresent("ch.qos.logback.classic.LoggerContext",
Factory.class.getClassLoader());
@Override
public LoggingSystem getLoggingSystem(ClassLoader classLoader) {
if (PRESENT) {
return new LogbackLoggingSystem(classLoader);
}
return null;
}
}1-3 Change to log4j2
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web:")
implementation("org.springframework.boot:spring-boot-starter-aop:")
implementation("org.springframework.boot:spring-boot-starter-log4j2")
}
configurations.all {
exclude(group = "org.springframework.boot", module = "spring-boot-starter-logging")
}这个时候通过断点 发现生效的就是 org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory 了
1-4 Console is colored
什么时候会触发 彩色机制. 根据如下配置:
spring:
output:
ansi:
enabled: detected默认就是 detected, 如下:
private static Enabled enabled = Enabled.DETECT;探测代码位于 org.springframework.boot.ansi.AnsiOutput#detectIfAnsiCapable .
- 一个关键点就是
System.console() != null, 这个就是jvm返回的console对象,如果存在就大概率支持ANSI, 返回null也不能说明不支持,所以喜欢的话就强制,colored. 理想 的情况是dev环境colored,online环境就算了,不要这些奇怪的乱码.
2-2 devops-logging
graph TD A[开始] --> B[获取应用名称] B --> C[获取日志路径] C --> D{日志路径是否存在且不是目录?} D -->|是| E[设置默认日志路径] D -->|否| F[保持原日志路径] E --> G[确保日志路径以斜杠结尾] F --> G G --> H[遍历所有LogAppenderType] H --> I[调用setFileProperty方法] I --> J{是否还有更多LogAppenderType?} J -->|是| H J -->|否| K[结束] subgraph setFileProperty方法 L[开始] --> M{logType.fileName是否存在?} M -->|是| N[设置文件名属性] M -->|否| O{logType.filePattern是否存在?} N --> O O -->|是| P[设置文件模式属性] O -->|否| Q[结束setFileProperty] P --> Q end