You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ruby+Logstash修改Item标签外的XML objectMessage内容

需求与解决方案

问题背景

我是Ruby新手,现有如下格式的XML日志文件:

<QuerySiteInformation>
    xmlns="http://www.abc-dd-cfff.com/aws/elastic/azure"
    <Site>
        <id>abc-cde-fvvvv</id>
        <objectMessage>Internal> message shown here in multiple lines</objectMessage>
        <Item>
            <id>e5753ead-d202-451e-92cc-ea49d0a6bdf5</id>
            <code>67448833344443</code>
            <objectMessage>Internal> message shown here in multiple lines</objectMessage>
            <reference>/</reference>
        </Item>
    </Site>
    <SiteInteraction>
        <InteractionItem>
            <Location>
                <id>8496940--2842047577555</id>
                <objectMessage>Internal> message shown here in multiple lines</objectMessage>
            </Location>
        </InteractionItem>
            <objectMessage>Internal> message shown here in multiple lines</objectMessage>
    </SiteInteraction>
</QuerySiteInformation>

注:Internal> message shown here in multiple lines 可出现在日志任意位置。

需求:仅当<objectMessage>标签位于<Item>标签外部时,将其内容替换为“MESSAGE HAS BEEN REMOVED”,预期效果如下:

<QuerySiteInformation>
    xmlns="http://www.abc-dd-cfff.com/aws/elastic/azure"
    <Site>
        <id>abc-cde-fvvvv</id>
        <objectMessage>Internal> MESSAGE HAS BEEN REMOVED</objectMessage>
        <Item>
            <id>e5753ead-d202-451e-92cc-ea49d0a6bdf5</id>
            <code>67448833344443</code>
            <objectMessage>Internal> message shown here in multiple lines</objectMessage>
            <reference>/</reference>
        </Item>
    </Site>
    <SiteInteraction>
        <InteractionItem>
            <Location>
                <id>8496940--2842047577555</id>
                <objectMessage>Internal> MESSAGE HAS BEEN REMOVED</objectMessage>
            </Location>
        </InteractionItem>
            <objectMessage>Internal> MESSAGE HAS BEEN REMOVED</objectMessage>
    </SiteInteraction>
</QuerySiteInformation>

之前的Logstash配置会修改<Item>节点内的标签内容,现在需要实现反向逻辑:

filter {
    xml {
        source => "message"
        target => "xml"
        store_xml => true
        remove_field => ["message"]
    }
}

filter {
  ruby {
    code => '
      event.get("[xml][Site][0][Item]").each_with_index do |item, index|
        event.set("[xml][Site][0][Item][#{index}]", "MESSAGE HAS BEEN REMOVED")
      end 
    '
  }
}

output {
    stdout {
        codec => rubydebug
    }
}

修改后的Logstash配置

要实现只替换<Item>外部的<objectMessage>内容,我们需要遍历XML解析后的结构,跳过<Item>内部的节点,替换其他所有<objectMessage>的值。以下是调整后的配置:

filter {
    xml {
        source => "message"
        target => "xml"
        store_xml => true
        remove_field => ["message"]
        force_array => false # 避免单节点自动转为数组,可根据实际日志调整
    }
}

filter {
  ruby {
    code => '
      # 递归处理节点,跳过Item内部的objectMessage
      def process_node(node)
        return unless node.is_a?(Hash)
        
        node.each do |key, value|
          if key == "Item"
            # 遇到Item节点直接跳过,不处理内部内容
            next
          elsif key == "objectMessage"
            # 替换Item外部的objectMessage内容
            node[key] = "Internal> MESSAGE HAS BEEN REMOVED"
          else
            # 递归处理子哈希节点
            process_node(value) if value.is_a?(Hash)
            # 遍历处理数组类型的子节点
            value.each { |item| process_node(item) } if value.is_a?(Array)
          end
        end
      end

      # 从XML根节点开始处理
      process_node(event.get("xml"))
    '
  }
}

output {
    stdout {
        codec => rubydebug
    }
    # 若需要输出回XML格式,可启用以下配置
    # xml {
    #     source => "xml"
    #     target => "message"
    #     root_element => "QuerySiteInformation"
    # }
}

代码说明

  1. 递归遍历逻辑:通过process_node函数遍历整个XML解析后的哈希结构,遇到<Item>节点直接跳过,确保其内部的<objectMessage>不被修改;遇到目标节点则替换内容。
  2. 数组兼容处理:考虑到日志中可能存在多个同层级节点(比如多个<Site>),代码会判断值是否为数组,遍历每个元素进行递归处理。
  3. force_array配置:xml插件的force_array设为false,避免单个节点被自动转为数组,简化处理逻辑;如果日志存在多个同类型节点,可调整为true适配。

内容的提问来源于stack exchange,提问作者CA-CB-TellMe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 11:01:08