# frozen_string_literal: true# Released under the MIT License.# Copyright, 2019-2024, by Samuel Williams.# Copyright, 2019, by Bryan Powell.# Copyright, 2020, by Michael Adams.# Copyright, 2021, by Robert Schulze.moduleConsoleUNKNOWN=:unknownclassFilterifObject.const_defined?(:Ractor)andRUBY_VERSION>="3.1"defself.define_immutable_method(name,&block)block=Ractor.make_shareable(block)self.define_method(name,&block)endelsedefself.define_immutable_method(name,&block)define_method(name,&block)endenddefself.[]**levelsklass=Class.new(self)minimum_level,maximum_level=levels.values.minmaxklass.instance_execdoconst_set(:LEVELS,levels.freeze)const_set(:MINIMUM_LEVEL,minimum_level)const_set(:MAXIMUM_LEVEL,maximum_level)levels.eachdo|name,level|const_set(name.to_s.upcase,level)define_immutable_method(name)do|subject=nil,*arguments,**options,&block|ifself.enabled?(subject,level)@output.call(subject,*arguments,severity: name,**@options,**options,&block)endenddefine_immutable_method("#{name}!")do@level=levelenddefine_immutable_method("#{name}?")do@level<=levelendendendreturnklassenddefinitialize(output,verbose: true,level: self.class::DEFAULT_LEVEL,**options)@output=output@verbose=verbose@level=level@subjects={}@options=optionsenddefwith(level: @level,verbose: @verbose,**options)dup.tapdo|logger|logger.level=levellogger.verbose!ifverboselogger.options=@options.merge(options)endendattr_accessor:outputattr:verboseattr:levelattr:subjectsattr_accessor:optionsdeflevel=leveliflevel.is_a?Symbol@level=self.class::LEVELS[level]else@level=levelendenddefverbose!(value=true)@verbose=value@output.verbose!(value)enddefoff!@level=self.class::MAXIMUM_LEVEL+1enddefall!@level=self.class::MINIMUM_LEVEL-1enddeffilter(subject,level)unlesssubject.is_a?(Module)raiseArgumentError,"Expected a class, got #{subject.inspect}"end@subjects[subject]=levelend# You can enable and disable logging for classes. This function checks if logging for a given subject is enabled.# @param subject [Object] the subject to check.defenabled?(subject,level=self.class::MINIMUM_LEVEL)subject=subject.classunlesssubject.is_a?(Module)ifspecific_level=@subjects[subject]returnlevel>=specific_levelendiflevel>=@levelreturntrueendend# Enable specific log level for the given class.# @parameter name [Module] The class to enable.defenable(subject,level=self.class::MINIMUM_LEVEL)# Set the filter level of logging for a given subject which passes all log messages:filter(subject,level)enddefdisable(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# Clear any specific filters for the given class.# @parameter name [Module] The class to disable.defclear(subject)unlesssubject.is_a?(Module)raiseArgumentError,"Expected a class, got #{subject.inspect}"end@subjects.delete(subject)enddefcall(subject,*arguments,**options,&block)severity=options[:severity]||UNKNOWNlevel=self.class::LEVELS[severity]ifself.enabled?(subject,level)@output.call(subject,*arguments,**options,&block)endendendend