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