Class: Console::Filter

Inherits:
Object
  • Object
show all
Defined in:
lib/console/filter.rb

Overview

A log filter which can be used to filter log messages based on severity, subject, and other criteria.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(output, verbose: true, level: nil, **options) ⇒ Filter

Create a new log filter.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/console/filter.rb', line 78

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

Instance Attribute Details

#levelObject

Returns the value of attribute level.



115
116
117
# File 'lib/console/filter.rb', line 115

def level
  @level
end

#optionsObject

Returns the value of attribute options.



121
122
123
# File 'lib/console/filter.rb', line 121

def options
  @options
end

#outputObject

Returns the value of attribute output.



109
110
111
# File 'lib/console/filter.rb', line 109

def output
  @output
end

#subjectsObject (readonly)

Returns the value of attribute subjects.



118
119
120
# File 'lib/console/filter.rb', line 118

def subjects
  @subjects
end

#The current log level.(currentloglevel.) ⇒ Object (readonly)



115
# File 'lib/console/filter.rb', line 115

attr :level

#The log levels for specific subject (classes).(loglevels) ⇒ Object (readonly)



118
# File 'lib/console/filter.rb', line 118

attr :subjects

#verboseObject (readonly)

Returns the value of attribute verbose.



112
113
114
# File 'lib/console/filter.rb', line 112

def verbose
  @verbose
end

Class Method Details

.[](**levels) ⇒ Object

Create a new log filter with specific log levels.

“‘ruby class MyLogger < Console::Filter[debug: 0, okay: 1, bad: 2, terrible: 3] “`



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
# File 'lib/console/filter.rb', line 35

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)
		
		# The default log level for instances of this filter class.
		# Set to MINIMUM_LEVEL to allow all messages by default.
		const_set(:DEFAULT_LEVEL, minimum_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

.define_immutable_method(name, &block) ⇒ Object

Define a method.



17
18
19
20
# File 'lib/console/filter.rb', line 17

def self.define_immutable_method(name, &block)
	block = Ractor.make_shareable(block)
	self.define_method(name, &block)
end

Instance Method Details

#Additional options.=(options. = (value)) ⇒ Object



121
# File 'lib/console/filter.rb', line 121

attr_accessor :options

#all!Object

Enable all logging.



148
149
150
# File 'lib/console/filter.rb', line 148

def all!
	@level = self.class::MINIMUM_LEVEL - 1
end

#call(subject, *arguments, **options, &block) ⇒ Object

Log a message with the given severity.

If the severity is not defined in this filter’s LEVELS (e.g., when chaining filters with different severity levels), the message is passed through to the output without filtering. This allows custom filters to be composed together.



223
224
225
226
227
228
229
230
231
232
233
# File 'lib/console/filter.rb', line 223

def call(subject, *arguments, **options, &block)
	severity = options[:severity] || UNKNOWN
	level = self.class::LEVELS[severity]
	
	# If the severity is unknown (level is nil), pass through to output without filtering:
	if level.nil? || self.enabled?(subject, level)
		@output.call(subject, *arguments, **options, &block)
	end
	
	return nil
end

#clear(subject) ⇒ Object

Clear any specific filters for the given class.



204
205
206
207
208
209
210
# File 'lib/console/filter.rb', line 204

def clear(subject)
	unless subject.is_a?(Module)
		raise ArgumentError, "Expected a class, got #{subject.inspect}"
	end
	
	@subjects.delete(subject)
end

#disable(subject) ⇒ Object

Disable logging for the given class.



196
197
198
199
# File 'lib/console/filter.rb', line 196

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

#enable(subject, level = self.class::MINIMUM_LEVEL) ⇒ Object

Enable specific log level for the given class.



188
189
190
191
# File 'lib/console/filter.rb', line 188

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

#enabled?(subject, level = self.class::MINIMUM_LEVEL) ⇒ Boolean

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.

Returns:

  • (Boolean)


173
174
175
176
177
178
179
180
181
182
183
# File 'lib/console/filter.rb', line 173

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

#filter(subject, level) ⇒ Object

Filter log messages based on the subject and log level.

You must provide the subject’s class, not an instance of the class.



158
159
160
161
162
163
164
# File 'lib/console/filter.rb', line 158

def filter(subject, level)
	unless subject.is_a?(Module)
		raise ArgumentError, "Expected a class, got #{subject.inspect}"
	end
	
	@subjects[subject] = level
end

#off!Object

Disable all logging.



143
144
145
# File 'lib/console/filter.rb', line 143

def off!
	@level = self.class::MAXIMUM_LEVEL + 1
end

#The output destination.=(outputdestination. = (value)) ⇒ Object



109
# File 'lib/console/filter.rb', line 109

attr_accessor :output

#verbose!(value = true) ⇒ Object

Set verbose output (enable by default with no arguments).



137
138
139
140
# File 'lib/console/filter.rb', line 137

def verbose!(value = true)
	@verbose = value
	@output.verbose!(value)
end

#Whether to enable verbose output.=(toenableverboseoutput. = (value)) ⇒ Object



112
# File 'lib/console/filter.rb', line 112

attr :verbose

#with(level: @level, verbose: @verbose, **options) ⇒ Object

Create a new log filter with the given options, from an existing log filter.



100
101
102
103
104
105
106
# File 'lib/console/filter.rb', line 100

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