Ruby - устанавливает разные уровни логов для разных целей - PullRequest
0 голосов
/ 31 мая 2018

Хотите знать, как установить разные уровни журнала для разных целей.Ниже мой Ruby код, который записывает строки в Console и File.

# https://stackoverflow.com/a/6407200
class MultiIO
  def initialize(*targets)
    @targets = targets
  end

  def write(*args)
    @targets.each do |t|
      t.write(*args)
    end
  end

  def close
    @targets.each(&:close)
  end
end

module Logging
  def self.logger(logname, programname, debug = false)
    log_file = File.open(logname, "a")
    log_file.sync = true
    zlogger = Logger.new MultiIO.new(log_file, STDOUT)
    zlogger.level = Logger::INFO
    zlogger.progname = programname
    zlogger.formatter = proc do |serverity, datetime, progname, msg|
      "#{datetime.strftime('%Y-%m-%d %I:%M:%S %p %:::z %Z')} - #{serverity} - [#{progname}] | #{msg}\n"
    end

    zlogger
  end
end

Я могу установить уровень отладки, если найдена специальная переменная env, $logger.level = Logger::DEBUG if ENV['enable_debug_logs'] == 'true'

Но, не уверен, как всегда писать Debugстроки в файле журнала и только Info строки в консоли.

Кто-нибудь знает?Любая помощь с благодарностью!

1 Ответ

0 голосов
/ 31 мая 2018

Поскольку уровень журнала является свойством регистратора , а не IO, мне кажется, что вам действительно нужно определить MultiLogger, а не MultiIO,Что-то вроде:

class MultiLogger
  attr_reader :default_level, :default_progname, :default_formatter

  def initialize(**args)
    @default_level = args[:default_level]
    @default_progname = args[:default_progname]
    @default_formatter = args[:default_formatter]
    @loggers = []

    Array(args[:loggers]).each { |logger| add_logger(logger) }
  end

  def add_logger(logger)
    logger.level = default_level if default_level
    logger.progname = default_progname if default_progname
    logger.formatter = default_formatter if default_formatter
    @loggers << logger
  end

  def close
    @loggers.map(&:close)
  end

  Logger::Severity.constants.each do |level|
    define_method(level.downcase) do |*args|                
      @loggers.each { |logger| logger.send(__method__, args) }
    end

    # These methods are a bit weird in the context of a "multi-logger" with varying levels,
    # since they are now returning an `Array`; never a falsey value.
    # You may want to define them differently, e.g. `@loggers.all? {...}`, or use a non-predicate method name here.
    define_method("#{level.downcase}?".to_sym) do
      @loggers.map(&__method__)
    end
  end
end

# Usage:

log_file = File.open(logname, "a")
log_file.sync = true 
file_logger = Logger.new(log_file)

console_logger = Logger.new(STDOUT)
console_logger.level = Logger::INFO

multi_logger = MultiLogger.new(
  default_progname: programname,
  default_formatter: proc do |severity, datetime, progname, msg|
      "#{datetime.strftime('%Y-%m-%d %I:%M:%S %p %:::z %Z')} - #{severity} - [#{progname}] | #{msg}\n"
    end,
  loggers: [file_logger, console_logger]
)
...