Class: Console::Resolver

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

Overview

Represents a class resolver that can be used to set log levels for different classes as they become available.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeResolver

Create a new class resolver.



63
64
65
66
67
# File 'lib/console/resolver.rb', line 63

def initialize
  @names = {}
  
  @trace_point = TracePoint.new(:class, &self.method(:resolve))
end

Class Method Details

.default_resolver(logger, env = ENV) ⇒ Object

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`.



22
23
24
25
26
27
28
29
30
31
32
33
34
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
# File 'lib/console/resolver.rb', line 22

def self.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
    .compact
  
  off_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:
  if on_klasses&.any?
    resolver ||= Resolver.new
    
    resolver.bind(on_klasses) do |klass|
      logger.enable(klass, logger.class::MINIMUM_LEVEL - 1)
    end
  end
  
  if off_klasses&.any?
    resolver ||= Resolver.new
    
    resolver.bind(off_klasses) do |klass|
      logger.disable(klass)
    end
  end
  
  levels.each do |level, names|
    resolver ||= Resolver.new
    
    resolver.bind(names) do |klass|
      logger.enable(klass, level)
    end
  end
  
  return resolver
end

Instance Method Details

#bind(names, &block) ⇒ Object

Bind the given class names to the given block. When the class name is resolved into an actual class, the block will be called with the class as an argument.

If the class is already defined, the block will be called immediately.

If the class is not defined, the block will be called when the class is defined, using a trace point.



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

def bind(names, &block)
  names.each do |name|
    if klass = Object.const_get(name) rescue nil
      yield klass
    else
      @names[name] = block
    end
  end
  
  if @names.any?
    @trace_point.enable
  else
    @trace_point.disable
  end
end

#resolve(trace_point) ⇒ Object

Invoked by the trace point when a class is defined.

This will call the block associated with the class name, if any, and remove it from the list of names to resolve.

If the list of names is empty, the trace point will be disabled.



105
106
107
108
109
110
111
112
113
# File 'lib/console/resolver.rb', line 105

def resolve(trace_point)
  if block = @names.delete(trace_point.self.to_s)
    block.call(trace_point.self)
  end
  
  if @names.empty?
    @trace_point.disable
  end
end

#waiting?Boolean

Returns:



94
95
96
# File 'lib/console/resolver.rb', line 94

def waiting?
  @trace_point.enabled?
end