module Ops class LogPatternMatcher Match = Struct.new(:name, :severity, :line, keyword_init: true) def initialize(patterns: nil) @patterns = patterns || load_patterns end def scan(text) return [] if text.blank? matches = [] text.each_line do |line| @patterns.each do |pattern| next unless line.match?(pattern[:regex]) matches << Match.new(name: pattern[:name], severity: pattern[:severity], line: line.strip) end end matches end private def load_patterns path = Rails.root.join("config/ops_log_patterns.yml") raw = YAML.safe_load(File.read(path), permitted_classes: [], aliases: true) || {} Array(raw["patterns"]).map do |entry| { name: entry["name"].to_s, severity: entry["severity"].to_s, regex: Regexp.new(entry["regex"], Regexp::IGNORECASE) } end end end end