dx网站是哪家公司做的,建设对公银行网站打不开,餐饮业网络营销方式,wordpress 工具当我们遇到问题或者需要深入了解 Elasticsearch 的运行机制时#xff0c;调整日志等级#xff08; logging level #xff09;到更详细的级别#xff0c;比如 DEBUG、TRACE #xff0c;会是一个有效且必须要掌握的方法。
Elasticsearch 提供了如下的接口来支持动态变更 l…当我们遇到问题或者需要深入了解 Elasticsearch 的运行机制时调整日志等级 logging level 到更详细的级别比如 DEBUG、TRACE 会是一个有效且必须要掌握的方法。
Elasticsearch 提供了如下的接口来支持动态变更 logging levellogger 后面是 package name 或者 class name。
PUT _cluster/settings
{persistent: {logger: {org.elasticsearch.action: DEBUG}}
}
当然你也可以去修改配置目录下面的 log4j2.properties然后重启节点但这种方法太过笨重建议你不要用。 如果后续想要调整回默认设置操作也简单如下所示 PUT _cluster/settings
{persistent: {logger: {org.elasticsearch.action: null}}
}
上面的示例只是指定了一个 logger当然也可以在一次请求中设定多个 logger如下所示
PUT _cluster/settings
{persistent: {logger: {_root: INFO,org.elasticsearch.action: DEBUG,org.elasticsearch.action.admin.cluster.health: TRACE}}
}
上面的设定中调用者的意图可能如下
root 的日志等级默认所有 logger 的日志级别设定为 INFO虽然 log4j2.properties 中已经设定过了保险起见这里再指定一次。设定 org.elasticsearch.action 这个 package 下所有 logger 的日志级别都为 DEBUG需要查看下 transport action 的执行日志。设定 org.elasticsearch.action.admin.cluster.health 这个 package 下所有 logger 的日志级别都为 TRACE需要查看 Cluster Health 执行的更多日志。
但实际去运行时Elasticsearch 并没有按照预期的结果去执行没有相关 DEBUG 和 TRACE 级别的日志输出。这里直接给出原因和解决方案。
原因是 elasticsearch 在设定 logging level 时会优先采用 _root 和 parent logger 的设定这里和 log4j2.properties 中的设定有所差异。
上面的调用最终结果是采用 _root 的设定所有 logger 都是 INFO 其他的设定都无效了。
解决方案如下去除 _root 设定和 parent logger 的设定。
PUT _cluster/settings
{persistent: {logger: {_root: null,org.elasticsearch.action: null,org.elasticsearch.action.admin.cluster.health: TRACE}}
}
下面就是源码分析了感兴趣的可以继续看下去~
源码分析
相关实现逻辑在 ClusterSetting.LoggingSettingUpdater 里面这里简单给下定位的思路感兴趣的同学可以自己去翻下源码。
rest 请求的入口是 RestClusterUpdateSettingsAction这里会转发请求到 master 节点master 处理的入口是 TransportClusterUpdateSettingsAction这里会去 update Cluster Setting关键词为 updater.updateSettings。在 updateSettings的时候会调用所有的 ClusterSettingUpdaterLogging 就是其中之一。
这里 apply setting 的代码如下
for (String key : value.keySet()) {assert loggerPredicate.test(key);String component key.substring(logger..length());if (level.equals(component)) {continue;}if (_root.equals(component)) {final String rootLevel value.get(key);if (rootLevel null) {Loggers.setLevel(LogManager.getRootLogger(), Loggers.LOG_DEFAULT_LEVEL_SETTING.get(settings));} else {Loggers.setLevel(LogManager.getRootLogger(), rootLevel);}} else {Loggers.setLevel(LogManager.getLogger(component), value.get(key));}
}
浅显易懂不废话而且这里的逻辑看起来很正常那么继续来看下 Loggers.setLevel代码。
public static void setLevel(Logger logger, Level level) {if (!LogManager.ROOT_LOGGER_NAME.equals(logger.getName())) {Configurator.setLevel(logger.getName(), level);} else {final LoggerContext ctx LoggerContext.getContext(false);final Configuration config ctx.getConfiguration();final LoggerConfig loggerConfig config.getLoggerConfig(logger.getName());loggerConfig.setLevel(level);ctx.updateLoggers();}// we have to descend the hierarchyfinal LoggerContext ctx LoggerContext.getContext(false);for (final LoggerConfig loggerConfig : ctx.getConfiguration().getLoggers().values()) {if (LogManager.ROOT_LOGGER_NAME.equals(logger.getName()) || loggerConfig.getName().startsWith(logger.getName() .)) {Configurator.setLevel(loggerConfig.getName(), level);}}
}
最后的处理逻辑会在每个 logger 设定完成后去重新刷一遍现有的 logger应用 root 或者 parent logger 的设定。
顺着代码的修改记录找到了当初的修改 PR 如下
[https://github.com/elastic/el...]()
其中也描述了修改的原因
Today when setting the logging level via the command-line or an API call, the expectation is that the logging level should trickle down the hiearchy to descendant loggers. However, this is not necessarily the case. For example, if loggers x and x.y are already configured then setting the logging level on x will not descend to x.y. This is because the logging config for x.y has already been forked from the logging config for x. Therefore, we must explicitly descend the hierarchy when setting the logging level and that is what this commit does. 从这段描述看当时要解决的问题是 x.y 没有继承 x logging level 的问题所以加了这段显示继承的逻辑。
虽然这解决了继承的问题但其行为本身与 log4j2.properties 中 logger 的修改逻辑就不一致了难免带来困扰。
但考虑到这个配置是一个专家级别的配置很少用户会使用自己心里明白正确的使用方法就好了^_^