class Smplkit::Logging::Adapters::StdlibLoggerAdapter

creation. The hook fires on every Logger.new call.
4. Uses +Module#prepend+ on ::Logger to catch new logger
3. Reports any logger explicitly registered via track.
2. Reports +“rails”+ if Rails.logger is defined.
1. Always reports +“root”+ at the framework default level.
logging.Logger.manager.loggerDict. Instead this adapter:
Ruby has no global logger registry like Python’s
subclasses, so Rails is covered automatically).
Adapter for Ruby stdlib Logger (which ActiveSupport::Logger

def adapters

def adapters
  @adapters ||= Concurrent::Array.new
end

def apply_level(logger_name, level)

def apply_level(logger_name, level)
  logger = @loggers[logger_name]
  return unless logger
  native = Levels.smpl_level_to_stdlib(level)
  logger.level = native
end

def build_hook

def build_hook
  Module.new do
    def initialize(*args, **kwargs)
      super
      StdlibLoggerAdapter.adapters.each do |adapter|
        adapter.on_new_logger_created(self, "logger.#{object_id}")
      rescue StandardError
        # Swallow to keep Logger.new robust under the hook.
      end
    end
  end
end

def discover

def discover
  rows = []
  @loggers.each_pair do |logger_name, logger|
    level = logger.level
    smpl_level = Levels.stdlib_level_to_smpl(level)
    rows << [logger_name, smpl_level, smpl_level]
  end
  if defined?(::Rails) && ::Rails.respond_to?(:logger) && ::Rails.logger
    track("rails", ::Rails.logger) unless @loggers.key?("rails")
    level = ::Rails.logger.level
    smpl_level = Levels.stdlib_level_to_smpl(level)
    rows << ["rails", smpl_level, smpl_level]
  end
  rows.uniq { |row| row[0] }
end

def global_lock

def global_lock
  @global_lock ||= Mutex.new
end

def hook_installed?

def hook_installed?
  !@hook_module.nil?
end

def initialize

def initialize
  super
  @loggers = Concurrent::Hash.new
  track_root!
  @on_new = nil
  @uninstalled = false
end

def initialize(*args, **kwargs)

def initialize(*args, **kwargs)
  super
  StdlibLoggerAdapter.adapters.each do |adapter|
    adapter.on_new_logger_created(self, "logger.#{object_id}")
  rescue StandardError
    # Swallow to keep Logger.new robust under the hook.
  end
end

def install_hook(&on_new_logger)

def install_hook(&on_new_logger)
  @on_new = on_new_logger
  @uninstalled = false
  self.class.global_lock.synchronize do
    unless self.class.hook_installed?
      hook = self.class.build_hook
      ::Logger.prepend(hook)
      self.class.instance_variable_set(:@hook_module, hook)
    end
    self.class.adapters << self
  end
end

def name

def name
  "stdlib-logger"
end

def on_new_logger_created(logger, name)

Called by the prepended hook when a new Logger is created.
def on_new_logger_created(logger, name)
  return if @uninstalled
  track(name, logger)
  smpl_level = Levels.stdlib_level_to_smpl(logger.level)
  @on_new&.call(name, smpl_level, smpl_level)
end

def reset_hook!

def reset_hook!
  @hook_module = nil
end

def track(logger_name, logger)

discovered and applied.
Register an additional logger with the adapter so its level can be
def track(logger_name, logger)
  @loggers[logger_name] = logger
end

def track_root!

def track_root!
  @loggers["root"] ||= ::Logger.new($stdout)
end

def uninstall_hook

def uninstall_hook
  @uninstalled = true
  self.class.global_lock.synchronize do
    self.class.adapters.delete(self)
  end
end