Removing item from array based on string value from another field

I have a ruby filter that puts all mac addresses (access points and stations macs) in a log to mac_addresses field and this works fine.
I also have another grok filter which puts only station mac addresses to station_mac field.
I'm trying to remove station_mac address from mac_addresses array if it has more than one address and then save result in different field.
The code below should be working but it doesn't remove station_mac from array so in result I get new field ap_macs with the same value as in mac_addresses.

ruby {
  code => "
    if event.get('mac_addresses').length > 1
      event.set('ap_macs', event.get('mac_addresses').delete_if { |a| a == event.get('station_mac')})
    end"
}

Are you expecting [mac_addresses] to be modified? That's not going to happen unless you make a call to event.set with the modified clone.

I was thinking of creating a new field [ap_macs] but if it's possible to modify [mac_addresses] then it could be even better. Unfortunatelly I'm not able to get it working either way.

When I run

input { generator { count => 1 lines => [ '' ] } }
filter {
    mutate { add_field => { mac_addresses => [ "1", "2", "3" ] "station_mac" => "2" } }
    ruby {
        code => '
            if event.get("mac_addresses").length > 1
                event.set("ap_macs", event.get("mac_addresses").delete_if { |a| a == event.get("station_mac")})
            end
        '
    }
}

I get

"mac_addresses" => [
    [0] "1",
    [1] "2",
    [2] "3"
],
      "ap_macs" => [
    [0] "1",
    [1] "3"
],
  "station_mac" => "2",

What exactly does your data look like? Try

output { stdout { codec => rubydebug } }

This is what I get when I use this filter

{
           "message" => "syslog: eventd_to_syslog():User[d0:87:e2:07:1d:59] leave WLAN[AVS-Media] at AP[R500 GoldMarvin@2c:c5:d3:3b:3c:80] with Session Time[495.20 sec] RX Bytes[16214] TX Bytes[62483] ",
           "ap_macs" => [
        [0] "d0:87:e2:07:1d:59",
        [1] "2c:c5:d3:3b:3c:80"
    ],
          "severity" => 6,
     "mac_addresses" => [
        [0] "d0:87:e2:07:1d:59",
        [1] "2c:c5:d3:3b:3c:80"
    ],
              "wlan" => "AVS-Media",
          "priority" => 134,
          "facility" => 16,
       "station_mac" => "d0:87:e2:07:1d:59",
    "facility_label" => "local0",
              "tags" => [
        [0] "ruby",
        [1] "logstash-1"
    ],
            "ap_mac" => "2c:c5:d3:3b:3c:80",
              "host" => "10.0.1.101",
        "input_type" => "syslog",
           "ap_name" => [
        [0] "R500 GoldMarvin"
    ],
          "@version" => "1",
    "severity_label" => "Informational",
        "@timestamp" => 2021-07-09T18:02:12.900Z
}

Your ruby code seems OK. There must be something else in the logic of the pipeline ... station_mac not set when the ruby filter executes, ruby filter in a conditional, or something else.

I can't believe it but you were right. I had my filter for [station_mac] just below this ruby filter. No comments about that.

Thanks for help.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.