I use following ruby code in ruby filter to remove empty fields and fields containing "-" from fields nested in "parentfield" . The code works 99% time well, but sometimes I get ruby exception "Ruby exception occurred: no implicit conversion of nil into String". What is wrong with this code?
ruby {
code => "
def walk_hash(parent, path, hash)
path << parent if parent
hash.each do |key, value|
walk_hash(key, path, value) if value.is_a?(Hash)
@paths << (path + [key]).map {|p| '[' + p + ']' }.join('')
end
path.pop
end
@paths = []
eventhash = event.to_hash
if eventhash.has_key?('parentfield') && eventhash['parentfield'].is_a?(Hash)
walk_hash('parentfield', [], eventhash['parentfield'])
end
@paths.each do |path|
value = event.get(path)
event.remove(path) if value.nil? || (value.respond_to?(:empty?) && value.empty?) || (value.is_a?(String) && value == '-')
end
"
}
It seems if I change this line: event.remove(path) if value.nil? || (value.respond_to?(:empty?) && value.empty?) || (value.is_a?(String) && value == '-')
to this: event.remove(path) if value.nil? || (value.respond_to?(:empty?) && value.empty?)
the issue disappears. But this will not do what I want. It will just remove empty fields (yes, almost all '-' fields shown in kibana means the value is null, but sometimes there is a - char).
Yes, I will try. But should not be event.remove(path) if value.nil? || (value.respond_to?(:empty?) && value.empty?) || (value.is_a?(String) && value == '-') working?
You mean that if value is nil you would expect if value.nil? to evaluate to true, resulting in all the ||'d conditions being short-circuited so that && value == '-' never gets evaluated? You might expect that, but you are telling me it does not work that way
Even if || will be processed all (which should not), (value.is_a?(String) && value == '-') contains condition to ensure value is String.
But I tried to do it in separate condition, so:
unless value.nil?
event.remove(path) if (value.is_a?(String) && value == '-')
end
It can not be shared between threads. @var is instance variable. I hope instance var is per thread (or is it per plugin instance globally?). There are too many events to be handled by just 1 worker. Also it could lead to a much longer time for the issue to occur so I can not test this.
I will try to change @paths to local variable (paths).
Hmm, it looks like there is one instance of one plugin configuration for each pipeline across all pipeline threads so probably @instance vars are shared ...
The first two events may have different random numbers because they both test @a is nil at the same time, but after that every event has the same random number. For example...
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.