物业网站建设武汉网站设计公司
1 日志级别
Spring Boot Actuator包括在运行时查看和配置应用程序日志级别的功能。您可以查看整个列表,也可以查看单个记录器的配置,该配置由显式配置的日志级别和日志框架给出的有效日志级别组成。这些级别可以是:
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
- FATAL
- OFF
- null
null表示没有显式配置。
2 logger接口
2.1 列表
GET /loggers
样例:
GET http://localhost:8087/actuator/loggers
Authorization: Basic dGVzdDpCQUtGWCQzbA==
2.2 详情
GET /loggers/{name:.*}
样例:
GET http://localhost:8087/actuator/loggers/sample.actuator.SampleActuatorApplication
Authorization: Basic dGVzdDpCQUtGWCQzbA==
2.3 修改level
POST /loggers/{name:.*}
样例:
POST http://localhost:8087/actuator/loggers/sample.actuator.SampleActuatorApplication
Authorization: Basic dGVzdDpCQUtGWCQzbA==
Content-Type: application/json
{
“configuredLevel”: “DEBUG”
}
3 分析
接口位于spring boot actuator 的LoggersMvcEndpoint
LoggersMvcEndpoint->LoggersEndpoint->LoggingSystem
3.1 LoggingSystem
LoggingSystem是接口,通过实现类具体处理
LoggingSystem实现类是通过LoggingSystem.get(get(ClassLoader classLoader)获得的
private static final Map<String, String> SYSTEMS;static {// LinkedHashMap 保证顺序性,logback、log4j、javalogging的顺序,加载到对应的类,就返回对应的LoggingSystem的实现类Map<String, String> systems = new LinkedHashMap<String, String>();systems.put("ch.qos.logback.core.Appender", "org.springframework.boot.logging.logback.LogbackLoggingSystem");systems.put("org.apache.logging.log4j.core.impl.Log4jContextFactory","org.springframework.boot.logging.log4j2.Log4J2LoggingSystem");systems.put("java.util.logging.LogManager", "org.springframework.boot.logging.java.JavaLoggingSystem");SYSTEMS = Collections.unmodifiableMap(systems);}public static LoggingSystem get(ClassLoader classLoader) {String loggingSystem = System.getProperty(SYSTEM_PROPERTY);if (StringUtils.hasLength(loggingSystem)) {if (NONE.equals(loggingSystem)) {return new NoOpLoggingSystem();}return get(classLoader, loggingSystem);}for (Map.Entry<String, String> entry : SYSTEMS.entrySet()) {if (ClassUtils.isPresent(entry.getKey(), classLoader)) {return get(classLoader, entry.getValue());}}throw new IllegalStateException("No suitable logging system located");}private static LoggingSystem get(ClassLoader classLoader, String loggingSystemClass) {try {Class<?> systemClass = ClassUtils.forName(loggingSystemClass, classLoader);return (LoggingSystem) systemClass.getConstructor(ClassLoader.class).newInstance(classLoader);}catch (Exception ex) {throw new IllegalStateException(ex);}}
LoggingSystem.get(get(ClassLoader classLoader)是通过LoggingApplicationListener调用的
3.2 LoggingApplicationListener
LoggingApplicationListener类图如下
在spring.factories发现LoggingApplicationListener配置,通过SpringFactoryLoader加载
初始化流程
注册到spring
调用流程
4 问题
4.1 安全
http接口可能会暴漏出去,存在安全问题。可以参照https://blog.csdn.net/weixin_43511928/article/details/129131251
- 指定management.port,独立于业务端口
- security.user.name、security.user.password配置账号密码(密码要使用强密码)
4.2 缺少reset
日志级别重置,恢复现场。
- 可以在setLogLevel记录被修改的名字、旧的日志级别
- 提供/logger/reset接口,setLogLevel恢复列表
4.3 只支持spring boot
4.3.1 参照对应日志框架LoggingSystem setLogLevel实现
LogbackLoggingSystem
@Overridepublic void setLogLevel(String loggerName, LogLevel level) {ch.qos.logback.classic.Logger logger = getLogger(loggerName);if (logger != null) {logger.setLevel(LEVELS.convertSystemToNative(level));}}
Log4J2LoggingSystem
@Overridepublic void setLogLevel(String loggerName, LogLevel logLevel) {Level level = LEVELS.convertSystemToNative(logLevel);LoggerConfig loggerConfig = getLoggerConfig(loggerName);if (loggerConfig == null) {loggerConfig = new LoggerConfig(loggerName, level, true);getLoggerContext().getConfiguration().addLogger(loggerName, loggerConfig);}else {loggerConfig.setLevel(level);}getLoggerContext().updateLoggers();}
4.3.2 使用arthas修改
参照 https://arthas.aliyun.com/doc/logger.html