Class: Lumberjack::LogEntryMatcher
- Inherits:
-
Object
- Object
- Lumberjack::LogEntryMatcher
- Defined in:
- lib/lumberjack/log_entry_matcher.rb
Overview
A flexible matching utility for testing and filtering log entries based on multiple criteria. This class provides pattern-based matching against log entry components including message content, severity levels, program names, and custom attributes with support for nested attribute structures.
The matcher uses Ruby's case equality operator (===) for flexible matching, supporting exact values, regular expressions, ranges, classes, and other pattern matching constructs. It's primarily designed for use with the Test device in testing scenarios but can be used anywhere log entry filtering is needed.
A matcher can optionally be constructed with an entry formatter. Filter values are always compared raw first. If a raw comparison fails, the filter value is run through the formatter and compared again. Since log entries are formatted before they are written to a device, this allows expectations to be written with unformatted values (an Exception, for example) and still match the formatted values captured on the entry.
Defined Under Namespace
Classes: IndifferentHash, Score
Instance Method Summary collapse
-
#closest(entries) ⇒ Lumberjack::LogEntry?
Find the closest matching log entry from a list of candidates.
-
#diff(entry) ⇒ Hash
Compare a log entry against the matcher criteria and return only the fields that do not match.
-
#initialize(message: nil, severity: nil, progname: nil, attributes: nil, formatter: nil) ⇒ LogEntryMatcher
constructor
Create a new log entry matcher with optional filtering criteria.
-
#match?(entry) ⇒ Boolean
Test whether a log entry matches all specified criteria.
Constructor Details
#initialize(message: nil, severity: nil, progname: nil, attributes: nil, formatter: nil) ⇒ LogEntryMatcher
Create a new log entry matcher with optional filtering criteria. All parameters are optional and nil values indicate no filtering for that component. The matcher uses case equality (===) for flexible pattern matching against each specified criterion.
51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/lumberjack/log_entry_matcher.rb', line 51 def initialize(message: nil, severity: nil, progname: nil, attributes: nil, formatter: nil) = .strip if .is_a?(String) @message_filter = @severity_filter = Severity.coerce(severity) if severity @progname_filter = progname if attributes @attributes_filter = attributes.is_a?(Hash) ? Utils.(attributes) : attributes end @formatter = resolve_formatter(formatter) @formatted_attribute_filters = {} end |
Instance Method Details
#closest(entries) ⇒ Lumberjack::LogEntry?
Find the closest matching log entry from a list of candidates. This method scores each entry based on how well it matches the specified criteria and returns the entry with the highest score, provided it meets a minimum threshold. If no entries meet the threshold, nil is returned.
129 130 131 132 133 |
# File 'lib/lumberjack/log_entry_matcher.rb', line 129 def closest(entries) scored_entries = entries.map { |entry| [entry, entry_score(entry)] } best_score = scored_entries.max_by { |_, score| score } (best_score&.last.to_f >= Score::MIN_SCORE_THRESHOLD) ? best_score.first : nil end |
#diff(entry) ⇒ Hash
Compare a log entry against the matcher criteria and return only the fields
that do not match. An empty hash means the entry matches, so
diff(entry).empty? is always equal to match?(entry).
The returned hash uses string keys for the fields ("message", "severity",
"progname", and "attributes"). Each mismatched field maps to a hash with
:expected and :actual (the entry value). Severity values are converted
to labels on both sides for readability. When a formatter is set and the
filter value was formatted, :expected shows the formatted filter value
so both sides of the mismatch are in the same form.
Attribute mismatches are reported per attribute using dot notation keys.
A missing attribute is reported with actual: nil. An attribute that was
expected to be absent (a nil or empty filter value) is reported with the
raw filter as :expected and the entry value as :actual. When the
attributes filter is not a hash (a matcher object applied to the whole
attributes hash), a failure is reported as a single hash with :expected
and :actual keys instead of per attribute detail.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 |
# File 'lib/lumberjack/log_entry_matcher.rb', line 94 def diff(entry) result = {} unless (entry.) result["message"] = {expected: , actual: entry.} end unless match_filter?(entry.severity, @severity_filter) result["severity"] = {expected: Severity.level_to_label(@severity_filter), actual: entry.severity_label} end unless match_filter?(entry.progname, @progname_filter) result["progname"] = {expected: @progname_filter, actual: entry.progname} end if @attributes_filter attributes = IndifferentHash.wrap(Utils.(entry.attributes)) if @attributes_filter.is_a?(Hash) mismatches = attribute_mismatches(attributes, @attributes_filter) result["attributes"] = mismatches unless mismatches.empty? elsif !match_filter?(attributes, @attributes_filter) result["attributes"] = {expected: @attributes_filter, actual: attributes} end end result end |
#match?(entry) ⇒ Boolean
Test whether a log entry matches all specified criteria. The entry must satisfy all non-nil filter conditions to be considered a match. Uses case equality (===) for flexible pattern matching.
69 70 71 |
# File 'lib/lumberjack/log_entry_matcher.rb', line 69 def match?(entry) diff(entry).empty? end |