Help with RUBY. Recognising field with prefix and changing its type

Hi, I am trying to convert fields with a certain prefix into an integer

      event.to_hash.keys.each { |k|
    if event.get[k].is_a?(String) and k.start_with?('behaviour_' || 'top_disease_')
      event.get[k] = event.set[k].to_i
    end
  }

Ideally I want to check prefix (for behaviour or top_disease) and then whether its a string.

I also found another post about this code structure; but it does not work either

    code => "event.set(k, v.to_f) if k.start_with?('behaviour_' || 'top_disease_')"

I have modified the RUBY code as under:

  ruby {
code => "
  event.to_hash.keys.each { |k|
    if event.get[k].start_with?('behaviour_' || 'top_disease_') and k.is_a?(String)
      event.get[k] = event.set[k].to_i
    end
  }
"}

By doing this, I am getting the following error:

Ruby exception occurred: wrong number of arguments calling 'get' <0 for 1>

Another try:

  ruby {
code => "
  event.to_hash.keys.each { |k|
    if event[k].start_with?('behaviour_' || 'top_disease_') and k.is_a?(String)
      event.set[k].to_i
    end
  }
"
}

I think your issue may come from the use of event.get/set functions :

ruby {
  code => "
    event.to_hash.keys.each { |k|
      if event.get(k).start_with?('behaviour_' || 'top_disease_') and k.is_a?(String)
        event.get(k) = event.set(k, k.to_i)
      end
    }
  "
}

There are over 50 fields... I have tried the mutate filter to convert them into integer. With the filter, it works. Further, these fields are created dynamically -- so the additions can be on-the-fly taking them to more than 50 in the near future. Is there any documentation about using the ruby plugin? The ruby-filter plugin guidelines are not very clear. I am unable to understand the get/set stuff.

There is another similar query but it is unresolved.

Yes I figured, this is why I have edited my answer and put my question back :yum:

Have you tried my solution ?

I tried it but it gives an unexpected "=" error in
event.get(k) = event.set(k, k.to_i)

my bad, try this :

ruby {
  code => "
    event.to_hash.keys.each { |k|
      if event.get(k).start_with?('behaviour_' || 'top_disease_')
        event.set(k, event.get(k).to_i)
      end
    }
  "
}

I think now we are getting somwhere.. I got the following error:

Ruby exception occurred: undefined method `start_with?' for nil:NilClass

I tried removed || with a , but it did not work and I got the same error.

ruby {
code => "
event.to_hash.keys.each { |k|
if event.get(k).start_with?('behaviour_' , 'top_disease_')
event.set(k, event.get(k).to_i)
end
}
"
}

try this :

ruby {
  code => "
    event.to_hash.keys.each { |k|
      if ( event.get(k).start_with?('behaviour_') || event.get(k).start_with?('top_disease_') )
        event.set(k, event.get(k).to_i)
      end
    }
  "
}

or

ruby {
  code => "
    event.to_hash.keys.each { |k|
      event.get(k).match('(behaviour|top_disease)_.*') {
        event.set(k, event.get(k).to_i)
      }
    }
  "
}

Still the undefined error for both start_with and match

any other ideas?

Hi Jainh, could you give us a sample event ?

Because the error let me think that your fields 'behaviour_' or 'top_disease_' are empty ... cf. Event API | Logstash Reference [8.11] | Elastic

Get API

The getter is a read-only access of field-based data in an Event.

Syntax: event.get(field)

Returns: Value for this field or nil if the field does not exist. Returned values could be a string, numeric or timestamp scalar value.

Remove your filter and print the output with

output {
  stdout {}
}

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