Я пытаюсь построить фильтр для logsatash. Это должно быть в Ruby.
Фильтр принимает метаданные в формате json и на основе другого json разрешенных полей удаляет все несоответствующие поля из метаданных.
Основная линия фильтра - сделать оценку. Если переданное имя метаданных находится в ключах разрешенного хэша, оно должно быть равно true
. (Все значения разрешенного хэша true
как в примере и не имеют значения).
В разрешенном хэше может быть glob , представленный подстановочным знаком *
, в таком случае он может соответствовать любой строке.
Например, "instrument.network.*"
означает, что "instrument.network.one"
или "instrument.network.abc"
могут пройти.
Но если нет *
, как в "event.type"
, может пройти только такая точная строка, но не "event.type.abc"
. Другими словами, *
представляет любое количество символов так же, как в регулярных выражениях.
Упрощенный код выглядит так:
# input data
metadata = {"event.type"=>"message", "instrument.network.one"=>false, "instrument.network.two"=>false, "other.meta"=>true}
@allowed = {"timestamp"=>true, "event.type"=>true, "network.labels.*"=>true}
metadata.each do |key, val|
# evaluation to be worked out
evaluation = (@allowed.has_key? key)
puts "the #{key} is allowed?: #{evaluation}"
# metadata clearence
metadata.delete(key) if !evaluation
end
puts "metadata after clearence: #{metadata}"
На данный момент вывод этого кода:
the event.type is allowed?: true
the instrument.network.one is allowed?: false
the instrument.network.two is allowed?: false
the other.meta is allowed?: false
metadata after clearence: {"event.type"=>"message"}
Но мне нужно, чтобы подстановочный знак, передаваемый из "network.labels.*"
, имел такой вывод:
the event.type is allowed?: true
the instrument.network.one is allowed?: true
the instrument.network.two is allowed?: true
the other.meta is allowed?: false
metadata after clearence: {"event.type"=>"message", "instrument.network.one"=>false, "instrument.network.two"=>false}
Я пытаюсь использовать Regexp.union(@allowed) =~ key
, но не могу заставить его работать таким образом. Я пробовал другие рубиновые трюки, такие как .find
и т. Д., Но не ожидал результата. Есть примеры использования одного регулярного выражения, поиск в массиве строк, но не наоборот.
Каким был бы Ruby способ построить такой фильтр?