lib/u3d/log_analyzer.rb in u3d-1.2.3 vs lib/u3d/log_analyzer.rb in u3d-1.3.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + ## --- BEGIN LICENSE BLOCK --- # Copyright (c) 2016-present WeWantToKnow AS # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal @@ -23,13 +25,13 @@ require 'json' require 'u3d/failure_reporter' module U3d # Analyzes log by filtering output along a set of rules - # rubocop:disable ClassLength, PerceivedComplexity, BlockNesting + # rubocop:disable Metrics/ClassLength, Metrics/PerceivedComplexity, Metrics/BlockNesting class LogAnalyzer - RULES_PATH = File.expand_path('../../../config/log_rules.json', __FILE__) + RULES_PATH = File.expand_path('../../config/log_rules.json', __dir__) MEMORY_SIZE = 10 def initialize @lines_memory = Array.new(MEMORY_SIZE) @active_phase = nil @@ -53,10 +55,11 @@ data.delete('GENERAL') data.each do |name, phase| # Phase parsing next unless phase['active'] next if phase['phase_start_pattern'].nil? + phase['phase_start_pattern'] = Regexp.new phase['phase_start_pattern'] phase['phase_end_pattern'] = Regexp.new phase['phase_end_pattern'] if phase['phase_end_pattern'] phase.delete('comment') # Rules parsing temp_rules = {} @@ -77,10 +80,11 @@ # Check if phase is changing @phases.each do |name, phase| next if name == @active_phase next unless line =~ phase['phase_start_pattern'] + finish_phase if @active_phase @active_phase = name UI.verbose("--- Beginning #{name} phase ---") break end @@ -114,16 +118,14 @@ @rule_lines_buffer.clear # It's not the end of the rules, should the line be stored? elsif rule['store_lines'] match = false - if rule['ignore_lines'] - rule['ignore_lines'].each do |pat| - if line =~ pat - match = true - break - end + rule['ignore_lines']&.each do |pat| + if line =~ pat + match = true + break end end @rule_lines_buffer << line.chomp unless match end end @@ -131,10 +133,11 @@ # If there is no active rule, try to apply a new one if @active_rule.nil? ruleset.each do |rn, r| pattern = r['start_pattern'] next unless line =~ pattern + @active_rule = rn if r['end_pattern'] match = line.match(pattern) @context = match.names.map(&:to_sym).zip(match.captures).to_h if r['fetch_line_at_index'] || r['fetch_first_line_not_matching'] if r['fetch_line_at_index'] @@ -143,14 +146,16 @@ fetched_line = nil @lines_memory.reverse.each do |l| match = false r['fetch_first_line_not_matching'].each do |pat| next unless l =~ pat + match = true break end next if match + fetched_line = l break end end if fetched_line @@ -194,11 +199,11 @@ def finish_phase if @active_rule # Active rule should be finished # If it is still active during phase change, it means that something went wrong - context = @lines_memory.map { |l| "> #{l}" }.join('') + context = @lines_memory.map { |l| "> #{l}" }.join UI.error("[#{@active_phase}] Could not finish active rule '#{@active_rule}'. Aborting it. Context:\n#{context}") U3d::FailureReporter.report( failure_type: "PRETTIFIER", failure_message: "Could not finish rule", @@ -235,28 +240,27 @@ UI.error("[U3D] Rule '#{@active_rule}' captures were incomplete: #{e.message}") end message end - def parse_rule(r) - return false unless r['active'] - return false if r['start_pattern'].nil? - r['start_pattern'] = Regexp.new r['start_pattern'] - r['end_pattern'] = Regexp.new r['end_pattern'] if r['end_pattern'] - if r['fetch_line_at_index'] - r.delete('fetch_line_at_index') if r['fetch_line_at_index'] >= MEMORY_SIZE - r.delete('fetch_line_at_index') if r['fetch_line_at_index'] <= 0 - elsif r['fetch_first_line_not_matching'] - r['fetch_first_line_not_matching'].map! { |pat| Regexp.new pat } + def parse_rule(rule) + return false unless rule['active'] + return false if rule['start_pattern'].nil? + + rule['start_pattern'] = Regexp.new rule['start_pattern'] + rule['end_pattern'] = Regexp.new rule['end_pattern'] if rule['end_pattern'] + if rule['fetch_line_at_index'] + rule.delete('fetch_line_at_index') if rule['fetch_line_at_index'] >= MEMORY_SIZE + rule.delete('fetch_line_at_index') if rule['fetch_line_at_index'] <= 0 + elsif rule['fetch_first_line_not_matching'] + rule['fetch_first_line_not_matching'].map! { |pat| Regexp.new pat } end - if r['fetch_line_at_index'] || r['fetch_first_line_not_matching'] - r['fetched_line_pattern'] = Regexp.new r['fetched_line_pattern'] if r['fetched_line_pattern'] - end - r['type'] = 'important' if r['type'] == 'warning' - r['type'] = 'message' if r['type'] && r['type'] != 'error' && r['type'] != 'important' && r['type'] != 'success' - r['type'] ||= 'message' - r['ignore_lines'].map! { |pat| Regexp.new pat } if r['ignore_lines'] + rule['fetched_line_pattern'] = Regexp.new rule['fetched_line_pattern'] if (rule['fetch_line_at_index'] || rule['fetch_first_line_not_matching']) && (rule['fetched_line_pattern']) + rule['type'] = 'important' if rule['type'] == 'warning' + rule['type'] = 'message' if rule['type'] && rule['type'] != 'error' && rule['type'] != 'important' && rule['type'] != 'success' + rule['type'] ||= 'message' + rule['ignore_lines']&.map! { |pat| Regexp.new pat } true end end - # rubocop:enable ClassLength, PerceivedComplexity, BlockNesting + # rubocop:enable Metrics/ClassLength, Metrics/PerceivedComplexity, Metrics/BlockNesting end