Spec-Zone.ru › Ruby 2.7

класс Logger

Родитель:
Объект
Включенные модули:

Описание

Класс Logger предоставляет простую, но функциональную утилиту для ведения логов, которую вы можете использовать для вывода сообщений.

Сообщения имеют связанные уровни, такие как INFO или ERROR, которые указывают на их важность. Затем вы можете задать Logger уровень, и будут выводиться только сообщения на этом уровне или выше.

Уровни:

UNKNOWN

Неизвестное сообщение, которое всегда должно быть записано в лог.

FATAL

Непреодолимая ошибка, приводящая к аварийному завершению программы.

ERROR

Обрабатываемая ошибка.

WARN

Предупреждение.

INFO

Общие (полезные) сведения об операциях системы.

DEBUG

Сведения низкого уровня для разработчиков.

Например, в производственной системе вы можете установить Logger на INFO или даже WARN. Однако во время разработки вы, вероятно, захотите узнать о внутреннем состоянии программы и установите Logger на DEBUG.

Примечание: Logger не экранирует и не очищает сообщения, передаваемые в него. Разработчики должны быть внимательны к тому, когда потенциально вредоносные данные (ввод пользователя) передаются в Logger, и вручную экранировать недоверенные данные:

logger.info("User-input: #{input.dump}")
logger.info("User-input: %p" % input)

Вы можете использовать formatter= для экранирования всех данных.

original_formatter = Logger::Formatter.new
logger.formatter = proc { |severity, datetime, progname, msg|
  original_formatter.call(severity, datetime, progname, msg.dump)
}
logger.info(input)

Пример

Это создает Logger, который выводит данные в стандартный поток вывода со значением уровня WARN.

require 'logger'

logger = Logger.new(STDOUT)
logger.level = Logger::WARN

logger.debug("Created logger")
logger.info("Program started")
logger.warn("Nothing to do!")

path = "a_non_existent_file"

begin
  File.foreach(path) do |line|
    unless line =~ /^(\w+) = (.*)$/
      logger.error("Line in wrong format: #{line.chomp}")
    end
  end
rescue => err
  logger.fatal("Caught exception; exiting")
  logger.fatal(err)
end

Поскольку уровень Logger установлен на WARN, регистрируются только предупреждения, ошибки и фатальные сообщения. Сообщения отладки и информационные сообщения игнорируются.

Особенности

Класс Logger предоставляет несколько интересных функций, таких как автоматическая ротация лог-файлов, настройка формата лог-сообщений и указание имени программы в сообщении. Следующий раздел показывает, как этого достичь.

Инструкции по использованию

Как создать логгер

Ниже приведены варианты, начиная от простых до более сложных.

  1. Создайте логгер, который записывает сообщения в STDERR/STDOUT.

    logger = Logger.new(STDERR)
    logger = Logger.new(STDOUT)
    
  2. Создайте логгер для файла с указанным именем.

    logger = Logger.new('logfile.log')
    
  3. Создайте логгер для указанного файла.

    file = File.open('foo.log', File::WRONLY | File::APPEND)
    # To create new logfile, add File::CREAT like:
    # file = File.open('foo.log', File::WRONLY | File::APPEND | File::CREAT)
    logger = Logger.new(file)
    
  4. Создайте логгер, который архивирует лог-файл по достижении определенного размера. Сохраняйте 10 «старых» лог-файлов, каждый размером приблизительно 1 024 000 байт.

    logger = Logger.new('foo.log', 10, 1024000)
    
  5. Создайте логгер, который архивирует лог-файл ежедневно/еженедельно/ежемесячно.

    logger = Logger.new('foo.log', 'daily')
    logger = Logger.new('foo.log', 'weekly')
    logger = Logger.new('foo.log', 'monthly')
    

Как записать сообщение в лог

Обратите внимание на различные методы (fatal, error, info) для записи сообщений разных уровней? Другие методы в этой группе — warn и debug. Ниже используется add для записи сообщения произвольного (возможно, динамического) уровня.

  1. Сообщение в блоке.

    logger.fatal { "Argument 'foo' not given." }
    
  2. Сообщение как строка.

    logger.error "Argument #{@foo} mismatch."
    
  3. С именем программы.

    logger.info('initialize') { "Initializing..." }
    
  4. С уровнем серьезности.

    logger.add(Logger::FATAL) { 'Fatal error!' }
    

Форма с блоком позволяет создавать потенциально сложные лог-сообщения, откладывая их оценку до тех пор, пока сообщение не будет записано в лог. Например, если у нас есть следующее:

logger.debug { "This is a " + potentially + " expensive operation" }

Если уровень логгера INFO или выше, сообщения отладки не будут записаны, и весь блок не будет даже проанализирован. Сравните с этим:

logger.debug("This is a " + potentially + " expensive operation")

Здесь конкатенация строк выполняется каждый раз, даже если уровень лога не настроен на отображение сообщения отладки.

Как закрыть логгер

logger.close

Настройка порога серьезности

  1. Исходный интерфейс.

    logger.sev_threshold = Logger::WARN
    
  2. Интерфейс, совместимый с Log4r (частично).

    logger.level = Logger::INFO
    
    # DEBUG < INFO < WARN < ERROR < FATAL < UNKNOWN
    
  3. Symbol или String (регистр не учитывается)

    logger.level = :info
    logger.level = 'INFO'
    
    # :debug < :info < :warn < :error < :fatal < :unknown
    
  4. Конструктор

    Logger.new(logdev, level: Logger::INFO)
    Logger.new(logdev, level: :info)
    Logger.new(logdev, level: 'INFO')
    

Формат

Лог-сообщения по умолчанию отображаются в выходном потоке в определенном формате. Ниже показан стандартный формат и пример:

Формат лога:

SeverityID, [DateTime #pid] SeverityLabel -- ProgName: message

Пример лога:

I, [1999-03-03T02:34:24.895701 #19074]  INFO -- Main: info.

Вы можете изменить формат даты и времени с помощью datetime_format=.

logger.datetime_format = '%Y-%m-%d %H:%M:%S'
      # e.g. "2004-01-03 00:54:26"

или через конструктор.

Logger.new(logdev, datetime_format: '%Y-%m-%d %H:%M:%S')

Или вы можете изменить общий формат через метод formatter=.

logger.formatter = proc do |severity, datetime, progname, msg|
  "#{datetime}: #{msg}\n"
end
# e.g. "2005-09-22 08:51:08 +0900: hello world"

или через конструктор.

Logger.new(logdev, formatter: proc {|severity, datetime, progname, msg|
  "#{datetime}: #{msg}\n"
})

Константы

ИмяПрограммы
МеткаУровняСерьезности

Метка уровня серьезности для ведения журнала (максимум 5 символов).

Атрибуты

форматер[RW]

Форматировщик логов, как Proc, который принимает четыре аргумента и возвращает отформатированное сообщение. Аргументами являются:

severity

Уровень серьезности лог-сообщения.

time

Объект Time, представляющий время регистрации сообщения.

progname

Настроенное progname или переданное в метод логгера.

msg

Объект, переданный пользователем в лог-сообщение; необязательно String.

Блок должен возвращать Object, который может быть записан в устройство ведения журнала через write. По умолчанию используется форматировщик, если он не задан.

уровень[R]

Порог серьезности ведения журнала (например, Logger::INFO).

имя_программы[RW]

Имя программы, которое следует включать в лог-сообщения.

sev_threshold[R]

Порог серьезности ведения журнала (например, Logger::INFO).

Методы открытого класса

new(logdev, shift_age = 0, shift_size = 1048576) Показать исходный код
new(logdev, shift_age = 'weekly')
new(logdev, level: :info)
new(logdev, progname: 'progname')
new(logdev, formatter: formatter)
new(logdev, datetime_format: '%Y-%m-%d %H:%M:%S')
# File lib/logger.rb, line 379
def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
               progname: nil, formatter: nil, datetime_format: nil,
               binmode: false, shift_period_suffix: '%Y%m%d')
  self.level = level
  self.progname = progname
  @default_formatter = Formatter.new
  self.datetime_format = datetime_format
  self.formatter = formatter
  @logdev = nil
  if logdev
    @logdev = LogDevice.new(logdev, shift_age: shift_age,
      shift_size: shift_size,
      shift_period_suffix: shift_period_suffix,
      binmode: binmode)
  end
end

Аргументы

logdev

Устройство ведения журнала. Это имя файла (String) или объект IO (обычно STDOUT, STDERR, или открытый файл).

shift_age

Количество старых лог-файлов для сохранения или частота ротации (daily, weekly или monthly). Значение по умолчанию — 0, что отключает ротацию лог-файлов.

shift_size

Максимальный размер лог-файла в байтах (применимо только когда shift_age — положительное Integer). Значение по умолчанию — 1048576 (1 МБ).

level

Порог серьезности ведения журнала. Значение по умолчанию — Logger::DEBUG.

progname

Имя программы для включения в лог-сообщения. Значение по умолчанию — null.

formatter

Форматировщик логов. Значение по умолчанию — экземпляр Logger::Formatter.

datetime_format

Формат даты и времени Date. Значение по умолчанию — '%Y-%m-%d %H:%M:%S'.

binmode

Использовать двоичный режим для устройства ведения журнала. Значение по умолчанию — false.

shift_period_suffix

Формат суффикса лог-файла для ротации daily, weekly или monthly. Значение по умолчанию — '%Y%m%d'.

Описание

Создать экземпляр.

Публичные методы экземпляра

<<(msg) Показать исходный код
# File lib/logger.rb, line 484
def <<(msg)
  @logdev&.write(msg)
end

Выгружает заданное сообщение в устройство регистрации без форматирования. Если устройство регистрации отсутствует, возвращает nil.

Logger#add(severity, message = nil, progname = nil) { ... } Показать исходный код
# File lib/logger.rb, line 458
def add(severity, message = nil, progname = nil)
  severity ||= UNKNOWN
  if @logdev.nil? or severity < level
    return true
  end
  if progname.nil?
    progname = @progname
  end
  if message.nil?
    if block_given?
      message = yield
    else
      message = progname
      progname = @progname
    end
  end
  @logdev.write(
    format_message(format_severity(severity), Time.now, progname, message))
  true
end

Аргументы

severity

Серьезность. Константы определены в пространстве имен Logger: DEBUG, INFO, WARN, ERROR, FATAL, или UNKNOWN.

message

Сообщение журнала. String или Exception.

progname

Строка имени программы. Может быть опущена. Рассматривается как сообщение, если не заданы message и block.

block

Может быть опущено. Вызывается для получения строки сообщения, если message имеет значение nil.

Возвращаемое значение

Когда заданная серьезность недостаточно высока (для этого конкретного регистратора), не регистрируется сообщение, и возвращается true.

Описание

Регистрирует сообщение, если заданная серьезность достаточно высока. Это универсальный метод регистрации. Пользователи будут чаще использовать debug, info, warn, error, и fatal.

Формат сообщения: message может быть любым объектом, но он должен быть преобразован в String, чтобы его можно было зарегистрировать. Как правило, используется inspect, если заданный объект не является String. Специальным случаем является объект Exception, который будет напечатан подробно, включая сообщение, класс и трассировку стека. См. msg2str для реализации, если необходимо.

Ошибки

  • Файл журнала не заблокирован.

  • Открытие в режиме добавления не требует блокировки файла.

  • Если ОС поддерживает многопоточный ввод-вывод, записи могут быть перемешаны.

Также имеет псевдоним: log
close() Показать исходный код
# File lib/logger.rb, line 571
def close
  @logdev&.close
end

Закрывает устройство регистрации.

datetime_format() Показать исходный код
# File lib/logger.rb, line 284
def datetime_format
  @default_formatter.datetime_format
end

Возвращает используемый формат даты. См. datetime_format=

datetime_format=(datetime_format) Показать исходный код
# File lib/logger.rb, line 279
def datetime_format=(datetime_format)
  @default_formatter.datetime_format = datetime_format
end

Set формат даты и времени.

datetime_format

Строка, подходящая для передачи в strftime.

debug(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 493
def debug(progname = nil, &block)
  add(DEBUG, nil, progname, &block)
end

Регистрирует сообщение DEBUG.

См. info для получения дополнительной информации.

debug!() Показать исходный код
# File lib/logger.rb, line 310
def debug!; self.level = DEBUG; end

Устанавливает серьезность в DEBUG.

debug?() Показать исходный код
# File lib/logger.rb, line 307
def debug?; level <= DEBUG; end

Возвращает true, если текущий уровень серьезности позволяет печатать сообщения DEBUG.

error(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 545
def error(progname = nil, &block)
  add(ERROR, nil, progname, &block)
end

Регистрирует сообщение ERROR.

См. info для получения дополнительной информации.

error!() Показать исходный код
# File lib/logger.rb, line 331
def error!; self.level = ERROR; end

Устанавливает серьезность в ERROR.

error?() Показать исходный код
# File lib/logger.rb, line 328
def error?; level <= ERROR; end

Возвращает true, если текущий уровень серьезности позволяет печатать сообщения ERROR.

fatal(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 554
def fatal(progname = nil, &block)
  add(FATAL, nil, progname, &block)
end

Регистрирует сообщение FATAL.

См. info для получения дополнительной информации.

fatal!() Показать исходный код
# File lib/logger.rb, line 338
def fatal!; self.level = FATAL; end

Устанавливает серьезность в FATAL.

fatal?() Показать исходный код
# File lib/logger.rb, line 335
def fatal?; level <= FATAL; end

Возвращает true, если текущий уровень серьезности позволяет печатать сообщения FATAL.

info(message) Показать исходный код
info(progname, &block)
# File lib/logger.rb, line 527
def info(progname = nil, &block)
  add(INFO, nil, progname, &block)
end

Регистрирует сообщение INFO.

message

Сообщение для регистрации; не обязательно должно быть String.

progname

В форме блока это progname, используемый в сообщении журнала. Значение по умолчанию может быть установлено с помощью progname=.

block

Вычисляется в сообщение для регистрации. Это не вычисляется, если уровень регистратора достаточно высок для регистрации сообщения. Это позволяет создавать потенциально дорогостоящие сообщения журнала, которые вызываются только тогда, когда регистратор настроен на их отображение.

Примеры

logger.info("MainApp") { "Received connection from #{ip}" }
# ...
logger.info "Waiting for input from user"
# ...
logger.info { "User typed #{input}" }

Вы, вероятно, будете придерживаться второй формы выше, если только вы не хотите указать имя программы (что вы также можете сделать с помощью progname=).

Возвращаемое значение

См. add.

info!() Показать исходный код
# File lib/logger.rb, line 317
def info!; self.level = INFO; end

Устанавливает серьезность в INFO.

info?() Показать исходный код
# File lib/logger.rb, line 314
def info?; level <= INFO; end

Возвращает true, если текущий уровень серьезности позволяет печатать сообщения INFO.

level=(severity) Показать исходный код
# File lib/logger.rb, line 250
def level=(severity)
  if severity.is_a?(Integer)
    @level = severity
  else
    case severity.to_s.downcase
    when 'debug'
      @level = DEBUG
    when 'info'
      @level = INFO
    when 'warn'
      @level = WARN
    when 'error'
      @level = ERROR
    when 'fatal'
      @level = FATAL
    when 'unknown'
      @level = UNKNOWN
    else
      raise ArgumentError, "invalid log level: #{severity}"
    end
  end
end

Устанавливает порог уровня протоколирования.

severity

Уровень серьезности сообщения журнала.

Также алиас: sev_threshold=
log(severity, message = nil, progname = nil)
Псевдоним для: add
Logger#reopen Показать исходный код
Logger#reopen(logdev)
# File lib/logger.rb, line 412
def reopen(logdev = nil)
  @logdev.reopen(logdev)
  self
end

Аргументы

logdev

Устройство протоколирования. Это имя файла (String) или объект IO (обычно STDOUT, STDERR, или открытый файл). Переоткрывает тот же файл, если он nil, ничего не делает для IO. По умолчанию nil.

Описание

Переоткрывает устройство протоколирования.

sev_threshold=(severity)
Псевдоним для: level=
unknown(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 564
def unknown(progname = nil, &block)
  add(UNKNOWN, nil, progname, &block)
end

Протоколирует сообщение UNKNOWN. Это сообщение будет выведено независимо от уровня журнала.

См. info для получения дополнительной информации.

warn(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 536
def warn(progname = nil, &block)
  add(WARN, nil, progname, &block)
end

Протоколирует сообщение WARN.

См. info для получения дополнительной информации.

warn!() Показать исходный код
# File lib/logger.rb, line 324
def warn!; self.level = WARN; end

Устанавливает уровень серьезности в WARN.

warn?() Показать исходный код
# File lib/logger.rb, line 321
def warn?; level <= WARN; end

Возвращает true, если текущий уровень серьезности позволяет выводить сообщения WARN.

Приватные методы экземпляра

format_message(severity, datetime, progname, msg) Показать исходный код
# File lib/logger.rb, line 584
def format_message(severity, datetime, progname, msg)
  (@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
format_severity(severity) Показать исходный код
# File lib/logger.rb, line 580
def format_severity(severity)
  SEV_LABEL[severity] || 'ANY'
end

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API