# Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com># # Permission is hereby granted, free of charge, to any person obtaining a copy# of this software and associated documentation files (the "Software"), to deal# in the Software without restriction, including without limitation the rights# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell# copies of the Software, and to permit persons to whom the Software is# furnished to do so, subject to the following conditions:# # The above copyright notice and this permission notice shall be included in# all copies or substantial portions of the Software.# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN# THE SOFTWARE.require_relative'filter'moduleConsoleclassResolver# You can change the log level for different classes using CONSOLE_<LEVEL> env vars.## e.g. `CONSOLE_WARN=Acorn,Banana CONSOLE_DEBUG=Cat` will set the log level for the classes Acorn and Banana to `warn` and Cat to `debug`. This overrides the default log level.## You can enable all log levels for a given class by using `CONSOLE_ON=MyClass`. Similarly you can disable all logging using `CONSOLE_OFF=MyClass`.## @parameter logger [Logger] A logger instance to set the logging levels on.# @parameter env [Hash] The environment to read levels from.## @returns [Nil] If there were no custom logging levels specified in the environment.# @returns [Resolver] If there were custom logging levels, then the created resolver is returned.defself.default_resolver(logger,env=ENV)# Find all CONSOLE_<LEVEL> variables from environment:levels=logger.class::LEVELS.map{|label,level|[level,env["CONSOLE_#{label.upcase}"]&.split(',')]}.to_h.compactoff_klasses=env['CONSOLE_OFF']&.split(',')on_klasses=env['CONSOLE_ON']&.split(',')resolver=nil# If we have any levels, then create a class resolver, and each time a class is resolved, set the log level for that class to the specified level:ifon_klasses&.any?resolver||=Resolver.newresolver.bind(on_klasses)do|klass|logger.enable(klass,logger.class::MINIMUM_LEVEL-1)endendifoff_klasses&.any?resolver||=Resolver.newresolver.bind(off_klasses)do|klass|logger.disable(klass)endendlevels.eachdo|level,names|resolver||=Resolver.newresolver.bind(names)do|klass|logger.enable(klass,level)endendreturnresolverenddefinitialize@names={}@trace_point=TracePoint.new(:class,&self.method(:resolve))enddefbind(names,&block)names.eachdo|name|ifklass=Object.const_get(name)rescuenilyieldklasselse@names[name]=blockendendif@names.any?@trace_point.enableelse@trace_point.disableendenddefwaiting?@trace_point.enabled?enddefresolve(trace_point)ifblock=@names.delete(trace_point.self.to_s)block.call(trace_point.self)endif@names.empty?@trace_point.disableendendendend