你真的知道如何查看 Elasticsearch 的 Debug 日志吗?!

news/2024/7/7 5:49:01 标签: elasticsearch, jenkins, 大数据

当我们遇到问题或者需要深入了解 Elasticsearch 的运行机制时,调整日志等级( logging level )到更详细的级别,比如 DEBUGTRACE ,会是一个有效且必须要掌握的方法。

Elasticsearch 提供了如下的接口来支持动态变更 logging level,logger 后面是 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"
    }
  }
}

上面的设定中,调用者的意图可能如下:

  1. root 的日志等级(默认所有 logger 的日志级别)设定为 INFO,虽然 log4j2.properties 中已经设定过了,保险起见,这里再指定一次。
  2. 设定 org.elasticsearch.action 这个 package 下所有 logger 的日志级别都为 DEBUG,需要查看下 transport action 的执行日志。
  3. 设定 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 里面,这里简单给下定位的思路,感兴趣的同学可以自己去翻下源码。

  1. rest 请求的入口是 RestClusterUpdateSettingsAction,这里会转发请求到 master 节点
  2. master 处理的入口是 TransportClusterUpdateSettingsAction,这里会去 update Cluster Setting,关键词为 updater.updateSettings
  3. 在 updateSettings的时候会调用所有的 ClusterSettingUpdater,Logging 就是其中之一。

这里 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 hierarchy
    final 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 的修改逻辑就不一致了,难免带来困扰。

但考虑到这个配置是一个专家级别的配置,很少用户会使用,自己心里明白正确的使用方法就好了^_^


http://www.niftyadmin.cn/n/5336090.html

相关文章

vue中引入sass、scss

常规步骤 1. 创建项目 使用vue cli 脚手架工具创建项目 vue create xxxx2. 创建全局样式文件 全局样式变量 路径:/assets/styles/variables.scss //flex 布局变量 $--flex-direction: ("row", "column"); $--flex-position: ("start"…

网络爬虫采集工具

在当今数字化的时代,获取海量数据对于企业、学术界和个人都至关重要。网络爬虫成为一种强大的工具,能够从互联网上抓取并提取所需的信息。本文将专心分享关于网络爬虫采集数据的全面指南,深入探讨其原理、应用场景以及使用过程中可能遇到的挑…

小程序宿主环境-组件swiper

巧识小程序的开发过程学习. 在我们的list.wxml中创建组件 <swiper class"swiper-container" indicator-dots indicator-color"white" indicator-active-color"grey" autoplay interval"2000" circular><!--第一个轮播图--&…

算法训练day17leetcode110平衡二叉树257二叉树的所有路径404左叶子之和

今日学习的文章和视频链接 https://www.bilibili.com/video/BV1GY4y1K7z8/?vd_source8272bd48fee17396a4a1746c256ab0ae https://programmercarl.com/0404.%E5%B7%A6%E5%8F%B6%E5%AD%90%E4%B9%8B%E5%92%8C.html#%E6%80%9D%E8%B7%AF 题目描述 给定一个二叉树&#xff0c;判…

Python自动化实战之接口请求的实现

在前文说过&#xff0c;如果想要更好的做接口测试&#xff0c;我们要利用自己的代码基础与代码优势&#xff0c;所以该章节不会再介绍商业化的、通用的接口测试工具&#xff0c;重点介绍如何通过 python 编码来实现我们的接口测试以及通过 Pycharm 的实际应用编写一个简单接口测…

Mermaid使用教程(绘制各种图)

Mermaid使用教程&#xff08;绘制各种图&#xff09; 文章目录 Mermaid使用教程&#xff08;绘制各种图&#xff09;简介饼状图简单的例子应用案例 序列图简单案例应用案例另一个应用案例 甘特图简单案例应用案例一个更为复杂的应用案例 Git图简单案例 总结 简介 本文将主要介…

如何在 ASP.NET Core 配置请求超时中间件

写在前面 本文参考官方文档&#xff0c;使用Asp.net core 8.0 的最小API 模板项目&#xff0c;配置超时中间件。 超时中间件可用于所有类型的ASP.NET Core应用&#xff1a;最小 API、带控制器的 Web API、MVC 和 Razor Pages。请求超时的属性位于命名空间 Microsoft.AspNetCo…

K8S--安装Nginx

原文网址&#xff1a;K8S--安装Nginx-CSDN博客 简介 本文介绍K8S安装Nginx的方法。 1.创建Nginx目录及配置文件 mkdir -p /work/devops/k8s/app/nginx/{config,html} 在config目录下创建nginx.conf配置文件&#xff0c;内容如下&#xff1a; # events必须要有 events {wo…