DefaultMergeStrategy - problem merging filters

未关闭
#3,173 6 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
java
领域
backend

调研方向

从 DefaultMergeStrategy#updateFilterNode 开始,使用 issue 中的 XML 配置示例比较两个 merge 分支。验证源过滤器子项是否得到保留,以及组合过滤器是否被展平而不是嵌套。完成的标准是,合并后的配置保留所有过滤器和 KeyValuePair 子项,并具有预期的组合结构。

由索引模型根据 Issue 内容生成。

描述

DefaultMergeStrategy (Log4j 2.24.1)

In DefaultMergeStrategy#updateFilterNode I think there is a problem when merging two configurations with filters and the target does not yet contain a CompositeFilter. (in the code below this is the elsecase).

private void updateFilterNode(
        final Node target,
        final Node targetChildNode,
        final Node sourceChildNode,
        final PluginManager pluginManager) {
    if (CompositeFilter.class.isAssignableFrom(targetChildNode.getType().getPluginClass())) {
        final Node node = new Node(targetChildNode, sourceChildNode.getName(), sourceChildNode.getType());
        node.getChildren().addAll(sourceChildNode.getChildren());
        node.getAttributes().putAll(sourceChildNode.getAttributes());
        targetChildNode.getChildren().add(node);
    } else {
        final PluginType pluginType = pluginManager.getPluginType(FILTERS);
        final Node filtersNode = new Node(targetChildNode, FILTERS, pluginType);
        final Node node = new Node(filtersNode, sourceChildNode.getName(), sourceChildNode.getType());
        node.getAttributes().putAll(sourceChildNode.getAttributes());
        final List<Node> children = filtersNode.getChildren();
        children.add(targetChildNode);
        children.add(node);
        final List<Node> nodes = target.getChildren();
        nodes.remove(targetChildNode);
        nodes.add(filtersNode);
    }
}

If I am not mistaken, there is a step missing to add the children of the 'sourceChildNode' to the new node.

I think it should be (see line commented with "<==== ADDED").

else {
        final PluginType pluginType = pluginManager.getPluginType(FILTERS);
        final Node filtersNode = new Node(targetChildNode, FILTERS, pluginType);
        final Node node = new Node(filtersNode, sourceChildNode.getName(), sourceChildNode.getType());
        node.getChildren().addAll(sourceChildeNode.getChildren());   // <==== ADDED
        node.getAttributes().putAll(sourceChildNode.getAttributes());
        final List<Node> children = filtersNode.getChildren();
        children.add(targetChildNode);
        children.add(node);
        final List<Node> nodes = target.getChildren();
        nodes.remove(targetChildNode);
        nodes.add(filtersNode);
    }
}

For example if merging a secondary configuration (source) containing the following filter to a base configuration (target) when the target contains a filter (but not a CompositeFilter):

<Configuration>
  <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"> 
    <KeyValuePair key="alice" value="DEBUG"/> 
    <KeyValuePair key="bob" value="INFO"/> 
  </DynamicThresholdFilter>
</Configuration>

I believe all the KeyValuePair children would be dropped during merge with the current code.

In addition, the current code does not account for the possibilty of the sourceChildNode being a CompositeFilter which would result in nested composite-filters. (this applies to both the ifand elsebranches of the original code.

<Configuration>
  <CompositeFilter>
     <Filter1/>
     <Filter2/>
  </CompositeFilter>
</Configuration>
<Configuration>
  <CompositeFilter>
     <Filter3/>
     <Filter4/>
  </CompositeFilter>
</Configuration>

Would result in:

<Configuration>
  <CompositeFilter>
     <Filter1/>
     <Filter2/>
     <CompositeFilter>
       <Filter3/>
       <Filter4/>
    </CompositeFilter>
  </CompositeFilter>
</Configuration>

But should probably be:

<Configuration>
  <CompositeFilter>
     <Filter1/>
     <Filter2/>
     <Filter3/>
     <Filter4/>
  </CompositeFilter>
</Configuration>
主要语言
Java
星标
3.6k
派生
1.8k
平均合并
5 天 6 小时
30 天内合并 PR
24

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 有 Pull Request 模板
  • 没有贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

apache/logging-log4j2 的其他 Issue

查看 apache/logging-log4j2 的全部 Issue

相似的 Issue

更多 Java Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。