Class: Lumberjack::LogEntryMatcher::Score
- Inherits:
-
Object
- Object
- Lumberjack::LogEntryMatcher::Score
- Defined in:
- lib/lumberjack/log_entry_matcher/score.rb
Overview
Class responsible for scoring and matching log entries against filters. This class provides fuzzy matching capabilities to find the best matching log entry when exact matches are not available.
Constant Summary collapse
- MIN_SCORE_THRESHOLD =
Minimum score threshold for considering a match (30% match)
0.3
Class Method Summary collapse
-
.calculate_attributes_score(entry_attributes, attributes_filter) ⇒ Float
Calculate score for attribute matching.
-
.calculate_field_score(value, filter) ⇒ Float
Calculate score for any field value against a filter.
-
.calculate_match_score(entry, message: nil, severity: nil, attributes: nil, progname: nil) ⇒ Float
Calculate the overall match score for an entry against all provided filters.
-
.severity_proximity_score(entry_severity, filter_severity) ⇒ Float
Calculate proximity score based on log severity distance.
Class Method Details
.calculate_attributes_score(entry_attributes, attributes_filter) ⇒ Float
Calculate score for attribute matching. Compares entry attributes against filter attributes and returns a score based on how many attributes match.
137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/lumberjack/log_entry_matcher/score.rb', line 137 def calculate_attributes_score(entry_attributes, attributes_filter) return 0.0 unless entry_attributes && attributes_filter.is_a?(Hash) attributes_filter = deep_stringify_keys(Lumberjack::Utils.(attributes_filter)) attributes = Lumberjack::LogEntryMatcher::IndifferentHash.wrap( deep_stringify_keys(Lumberjack::Utils.(entry_attributes)) ) total_attribute_filters = count_attribute_filters(attributes_filter) return 0.0 if total_attribute_filters == 0 matched_attributes = count_matched_attributes(attributes, attributes_filter) matched_attributes.to_f / total_attribute_filters end |
.calculate_field_score(value, filter) ⇒ Float
Calculate score for any field value against a filter. Returns a score between 0.0 and 1.0 based on how well the value matches the filter.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/lumberjack/log_entry_matcher/score.rb', line 87 def calculate_field_score(value, filter) return 0.0 unless value && filter case filter when String value_str = value.to_s if value_str == filter 1.0 elsif value_str.include?(filter) 0.7 else # Use string similarity for partial matching similarity = string_similarity(value_str, filter) (similarity > 0.5) ? similarity * 0.6 : 0.0 end when Regexp filter.match?(value.to_s) ? 1.0 : 0.0 else # For other matchers (like RSpec matchers), try to use === operator begin (filter === value) ? 1.0 : 0.0 rescue 0.0 end end end |
.calculate_match_score(entry, message: nil, severity: nil, attributes: nil, progname: nil) ⇒ Float
Calculate the overall match score for an entry against all provided filters. Returns a score between 0.0 and 1.0, where 1.0 represents a perfect match.
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/lumberjack/log_entry_matcher/score.rb', line 20 def calculate_match_score(entry, message: nil, severity: nil, attributes: nil, progname: nil) scores = [] weights = [] # Check message match if = calculate_field_score(entry., ) scores << weights << 0.5 # Weight message matching highly end # Check severity match if severity severity_score = if entry.severity == severity 1.0 # Exact severity match else severity_proximity_score(entry.severity, severity) # Partial severity match end scores << severity_score weights << 0.2 end # Check progname match if progname progname_score = calculate_field_score(entry.progname, progname) scores << progname_score weights << 0.2 end # Check attributes match if attributes.is_a?(Hash) unless attributes.empty? scores << calculate_attributes_score(entry.attributes, attributes) weights << 0.3 end elsif attributes # Matchers like RSpec's hash_including are applied to the attributes hash as a whole. entry_attributes = Lumberjack::LogEntryMatcher::IndifferentHash.wrap(Lumberjack::Utils.(entry.attributes)) scores << calculate_field_score(entry_attributes, attributes) weights << 0.3 end # Return 0 if no criteria were provided return 0.0 if scores.empty? # Calculate weighted average, but apply a penalty if any score is 0 # This ensures that completely failed criteria significantly impact the result total_weighted_score = scores.zip(weights).map { |score, weight| score * weight }.sum total_weight = weights.sum base_score = total_weighted_score / total_weight # Apply penalty for zero scores: reduce the score based on how many criteria completely failed zero_scores = scores.count(0.0) if zero_scores > 0 penalty_factor = 1.0 - (zero_scores.to_f / scores.length * 0.5) # Up to 50% penalty base_score *= penalty_factor end base_score end |
.severity_proximity_score(entry_severity, filter_severity) ⇒ Float
Calculate proximity score based on log severity distance. Provides partial scoring for severities that are close to the target.
120 121 122 123 124 125 126 127 128 |
# File 'lib/lumberjack/log_entry_matcher/score.rb', line 120 def severity_proximity_score(entry_severity, filter_severity) severity_diff = (entry_severity - filter_severity).abs case severity_diff when 0 then 1.0 when 1 then 0.7 when 2 then 0.4 else 0.0 end end |