Spec-Zone.ru › Ruby 2.5

класс Logger

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

Описание

Класс 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 (and to remove old) 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. С progname.

    logger.info('initialize') { "Initializing..." }
    
  4. С severity.

    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. Символ или строка (регистр не учитывается)

    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"
})

Константы

ProgName
SEV_LABEL

Метка Severity для ведения логов (макс. 5 символов).

VERSION

Атрибуты

formatter[RW]

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

severity

Severity лог-сообщения.

time

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

progname

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

msg

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

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

level[R]

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

progname[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 376
def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
               progname: nil, formatter: nil, datetime_format: nil,
               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)
  end
end

Аргументы

logdev

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

shift_age

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

shift_size

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

level

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

progname

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

formatter

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

datetime_format

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

shift_period_suffix

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

Описание

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

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

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

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

Logger#add(severity, message = nil, progname = nil) { ... } Показать исходный код
# File lib/logger.rb, line 454
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

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

message

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

progname

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

block

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

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

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

Описание

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

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

Ошибки

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

  • Добавление открытого файла не требует блокировки файла.

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

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

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

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

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

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

Устанавливает формат даты и времени.

datetime_format

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

message

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

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 326
def info?; @level <= INFO; end

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

level=(severity) Показать исходный код
# File lib/logger.rb, line 265
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

Severity сообщения журнала.

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

Аргументы

logdev

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

Описание

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

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

Записать UNKNOWN сообщение. Это сообщение будет выведено независимо от уровня регистрации.

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

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

Записать WARN сообщение.

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

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

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

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

format_message(severity, datetime, progname, msg) Показать исходный код
# File lib/logger.rb, line 582
def format_message(severity, datetime, progname, msg)
  (@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
format_severity(severity) Показать исходный код
# File lib/logger.rb, line 578
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