class Filter
A log filter which can be used to filter log messages based on severity, subject, and other criteria.
Definitions
def self.define_immutable_method(name, &block)
Define a method which can be shared between ractors.
Implementation
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)
Define a method.
Implementation
def self.define_immutable_method(name, &block)
define_method(name, &block)
end
def self.[] **levels
Create a new log filter with specific log levels.
class MyLogger < Console::Filter[debug: 0, okay: 1, bad: 2, terrible: 3]
Signature
-
parameter
levels
Hash(Symbol, Integer)
A hash of log levels.
Implementation
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 initialize(output, verbose: true, level: self.class::DEFAULT_LEVEL, **options)
Create a new log filter.
Signature
-
parameter
output
Console::Output
The output destination.
-
parameter
verbose
Boolean
Enable verbose output.
-
parameter
level
Integer
The log level.
-
parameter
options
Hash
Additional options.
Implementation
def initialize(output, verbose: true, level: self.class::DEFAULT_LEVEL, **options)
@output = output
@verbose = verbose
@level = level
@subjects = {}
@options = options
end
def with(level: @level, verbose: @verbose, **options)
Create a new log filter with the given options, from an existing log filter.
Signature
-
parameter
level
Integer
The log level.
-
parameter
verbose
Boolean
Enable verbose output.
-
parameter
options
Hash
Additional options.
-
returns
Console::Filter
The new log filter.
Implementation
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
attr_accessor :output
Signature
-
attribute
Console::Output
The output destination.
attr :verbose
Signature
-
attribute
Boolean
Whether to enable verbose output.
attr :level
Signature
-
attribute
Integer
The current log level.
attr :subjects
Signature
-
attribute
Hash(Module, Integer)
The log levels for specific subject (classes).
attr_accessor :options
Signature
-
attribute
Hash
Additional options.
def level= level
Set the log level.
Signature
-
parameter
level
Integer | Symbol
The log level.
Implementation
def level= level
if level.is_a? Symbol
@level = self.class::LEVELS[level]
else
@level = level
end
end
def verbose!(value = true)
Set verbose output (enable by default with no arguments).
Signature
-
parameter
value
Boolean
Enable or disable verbose output.
Implementation
def verbose!(value = true)
@verbose = value
@output.verbose!(value)
end
def off!
Disable all logging.
Implementation
def off!
@level = self.class::MAXIMUM_LEVEL + 1
end
def all!
Enable all logging.
Implementation
def all!
@level = self.class::MINIMUM_LEVEL - 1
end
def filter(subject, level)
Filter log messages based on the subject and log level.
You must provide the subject's class, not an instance of the class.
Signature
-
parameter
subject
Module
The subject to filter.
-
parameter
level
Integer
The log level.
Implementation
def filter(subject, level)
unless subject.is_a?(Module)
raise ArgumentError, "Expected a class, got #{subject.inspect}"
end
@subjects[subject] = level
end
def enabled?(subject, level = self.class::MINIMUM_LEVEL)
Whether logging is enabled for the given subject and log level.
You can enable and disable logging for classes. This function checks if logging for a given subject is enabled.
Signature
-
parameter
subject
Module
The subject to check.
-
parameter
level
Integer
The log level.
-
returns
Boolean
Whether logging is enabled.
Implementation
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 enable(subject, level = self.class::MINIMUM_LEVEL)
Enable specific log level for the given class.
Signature
-
parameter
name
Module
The class to enable.
Implementation
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 disable(subject)
Disable logging for the given class.
Signature
-
parameter
name
Module
The class to disable.
Implementation
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 clear(subject)
Clear any specific filters for the given class.
Signature
-
parameter
subject
Module
The class to disable.
Implementation
def clear(subject)
unless subject.is_a?(Module)
raise ArgumentError, "Expected a class, got #{subject.inspect}"
end
@subjects.delete(subject)
end
def call(subject, *arguments, **options, &block)
Log a message with the given severity.
Signature
-
parameter
subject
Object
The subject of the log message.
-
parameter
arguments
Array
The arguments to log.
-
parameter
options
Hash
Additional options to pass to the output.
-
parameter
block
Proc
A block passed to the output.
-
returns
Nil
Always returns nil.
Implementation
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