Logstash: Filter -> Mutate: copy the same field multiple times results in JRuby exception thrown

Created on 6 Aug 2019  路  8Comments  路  Source: elastic/logstash

When you try to copy the same field multiple times (to different destinations) the 2nd one always fails with a JRuby exception: "Cannot cast org.jruby.specialized.RubyArrayTwoObject to org.jruby.RubyString".

Version 7.2.0 in standard docker container (docker.elastic.co/logstash/logstash-oss:7.2.0)

Configuration

input {
  syslog {
    port => 1514
  }
}

filter {
    mutate {
      copy => { "[host]" => "[foo][bar]" }
      copy => { "[host]" => "[foo][baz]" }
    }
}

output {
  stdout { codec => rubydebug }
}

Reproduce

When logstash is running with the above config, simply send any message to port 1514; can even be a blank space as the input doesn't matter:

echo " " | nc -q0 localhost 1514

Log message

[2019-08-06T15:10:10,430][INFO ][logstash.inputs.syslog   ] new connection {:client=>"0:0:0:0:0:0:0:1:58584"}
[2019-08-06T15:10:10,543][WARN ][logstash.filters.mutate  ] Exception caught while applying mutate filter {:exception=>"Cannot cast org.jruby.specialized.RubyArrayTwoObject to org.jruby.RubyString"}
{
          "facility" => 0,
              "host" => "0:0:0:0:0:0:0:1",
          "severity" => 0,
        "@timestamp" => 2019-08-06T15:10:10.434Z,
    "severity_label" => "Emergency",
              "tags" => [
        [0] "_grokparsefailure_sysloginput",
        [1] "_mutate_error"
    ],
           "message" => " \n",
    "facility_label" => "kernel",
          "priority" => 0,
          "@version" => "1"
}

If you comment out the 2nd copy, it works without a problem. If you switch the order it still fails. If you comment out the 1st copy, it also works without a problem. Also doesn't matter what the name of the destination variable is, or whether it's a nested object or not. If you use multiple mutate blocks (one for each copy) it works fine.

I searched the documentation and could find no description of a restriction of using multiple copy's with the same source. And the error message is particularly unhelpful because it doesn't even tell you which part of the mutate is failing. This was part of a rather large mutate block with multiple copies, add_fields, remove_fields, strip, etc. Can the exception be caught in a better way and a better error message given? Even if the exception is part of the error message, there should at least be things like which mutate command, which line in the config, etc.

Most helpful comment

Working configuration(7.9.3):

filter {
    mutate {
      copy => { "[host]" => "[foo][bar]" }
      copy => { "[foo][bar]" => "[foo][baz]" }
    }
}

All 8 comments

OK, clearly there is a bug of some form here.

IMO a second copy function is unnecessary. The value for the copy is a hash, it can have many KV pairs in it.

copy => { "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" }

Sure, I realize the copy could be done in a single copy statement, but this problem came about because of a much larger config file with a lot of mutate statements that were grouped by functionality. So 2 different groups of statements were trying to copy the same field and to keep related things together they were done as 2 separate copy blocks.

Same issue on my side when trying to use 2 copy operation in same mutate plugin.

And getting following error :

[ERROR][logstash.inputs.metrics ] Failed to create monitoring event {:message=>"undefined method `[]' for nil:NilClass", :error=>"NoMethodError"}

as mentionned in #9126 (except the ephemeral_id -> empty on my side). Error seems similar.
I was checking the meaning of ruby error... that lead me to current issue. So when I fixed it (using only 1 COPY), the odd ruby error disappeared.

OK, clearly there is a bug of some form here.

IMO a second copy function is unnecessary. The value for the copy is a hash, it can have many KV pairs in it.

copy => { "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" "[host]" => "[foo][bar]" }

I suggest it should be added to docummentation how to use "copy" to multiple fields

I guess you meant:
copy => { "[host]" => "[foo][bar]" "[host]" => "[foo][baz]" }
for me this leads to
The given configuration is invalid. Reason: Duplicate keys found in your configuration: ["[host]"]

@marconfus yes, you are right! that is what I meant. So I guess it is not bug that you can not copy the same original field to 2 or more different fields? It is just a limitation. Are there any plans for implementing that?

Ah, ok. Then I misread the thread as "using a single copy operation is a functioning workaround"...

Working configuration(7.9.3):

filter {
    mutate {
      copy => { "[host]" => "[foo][bar]" }
      copy => { "[foo][bar]" => "[foo][baz]" }
    }
}
Was this page helpful?
0 / 5 - 0 ratings