class Console::Filter
A log filter which can be used to filter log messages based on severity, subject, and other criteria.
def self.[] **levels
```
class MyLogger < Console::Filter[debug: 0, okay: 1, bad: 2, terrible: 3]
```ruby
Create a new log filter with specific log levels.
def self.[] **levels klass = Class.new(self) minimum_level, maximum_level = levels.values.minmax klass.instance_exec do const_set(:LEVELS, levels.freeze) const_set(:MINIMUM_LEVEL, minimum_level) const_set(:MAXIMUM_LEVEL, maximum_level) levels.each do |name, level| const_set(name.to_s.upcase, level) define_immutable_method(name) do |subject = nil, *arguments, **options, &block| if self.enabled?(subject, level) @output.call(subject, *arguments, severity: name, **@options, **options, &block) end return nil end define_immutable_method("#{name}!") do @level = level end define_immutable_method("#{name}?") do @level <= level end end end return klass end
def self.define_immutable_method(name, &block)
def self.define_immutable_method(name, &block) block = Ractor.make_shareable(block) self.define_method(name, &block) end
def self.define_immutable_method(name, &block)
def self.define_immutable_method(name, &block) define_method(name, &block) end
def all!
def all! @level = self.class::MINIMUM_LEVEL - 1 end
def call(subject, *arguments, **options, &block)
@parameter block [Proc] A block passed to the output.
@parameter options [Hash] Additional options to pass to the output.
@parameter arguments [Array] The arguments to log.
@parameter subject [Object] The subject of the log message.
Log a message with the given severity.
def call(subject, *arguments, **options, &block) severity = options[:severity] || UNKNOWN level = self.class::LEVELS[severity] if self.enabled?(subject, level) @output.call(subject, *arguments, **options, &block) end return nil end
def clear(subject)
Clear any specific filters for the given class.
def clear(subject) unless subject.is_a?(Module) raise ArgumentError, "Expected a class, got #{subject.inspect}" end @subjects.delete(subject) end
def disable(subject)
Disable logging for the given class.
def disable(subject) # Set the filter level of the logging for a given subject which filters all log messages: filter(subject, self.class::MAXIMUM_LEVEL + 1) end
def enable(subject, level = self.class::MINIMUM_LEVEL)
Enable specific log level for the given class.
def enable(subject, level = self.class::MINIMUM_LEVEL) # Set the filter level of logging for a given subject which passes all log messages: filter(subject, level) end
def enabled?(subject, level = self.class::MINIMUM_LEVEL)
@parameter level [Integer] The log level.
@parameter subject [Module | Object] The subject to check.
You can enable and disable logging for classes. This function checks if logging for a given subject is enabled.
Whether logging is enabled for the given subject and log level.
def enabled?(subject, level = self.class::MINIMUM_LEVEL) subject = subject.class unless subject.is_a?(Module) if specific_level = @subjects[subject] return level >= specific_level end if level >= @level return true end end
def filter(subject, level)
@parameter subject [Module] The subject to filter.
You must provide the subject's class, not an instance of the class.
Filter log messages based on the subject and log level.
def filter(subject, level) unless subject.is_a?(Module) raise ArgumentError, "Expected a class, got #{subject.inspect}" end @subjects[subject] = level end
def initialize(output, verbose: true, level: nil, **options)
@parameter level [Integer] The log level.
@parameter verbose [Boolean] Enable verbose output.
@parameter output [Console::Output] The output destination.
Create a new log filter.
def initialize(output, verbose: true, level: nil, **options) @output = output @verbose = verbose # Set the log level using the behaviour implemented in `level=`: if level self.level = level else @level = self.class::DEFAULT_LEVEL end @subjects = {} @options = options end
def level= level
Set the log level.
def level= level if level.is_a? Symbol @level = self.class::LEVELS[level] else @level = level end end
def off!
def off! @level = self.class::MAXIMUM_LEVEL + 1 end
def verbose!(value = true)
Set verbose output (enable by default with no arguments).
def verbose!(value = true) @verbose = value @output.verbose!(value) end
def with(level: @level, verbose: @verbose, **options)
@parameter options [Hash] Additional options.
@parameter verbose [Boolean] Enable verbose output.
@parameter level [Integer] The log level.
Create a new log filter with the given options, from an existing log filter.
def with(level: @level, verbose: @verbose, **options) dup.tap do |logger| logger.level = level logger.verbose! if verbose logger.options = @options.merge(options) end end