Spec-Zone.ru › Ruby 3.1

класс 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 предоставляет несколько интересных функций, таких как автоматическое переименование файлов логов, установка формата сообщений логов и указание имени программы в сочетании с сообщением. Следующий раздел покажет, как это сделать.

Инструкции

Как создать Logger

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

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

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

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

    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. Создать Logger, который переименовывает лог-файл по достижении определенного размера. Оставить 10 «старых» лог-файлов, каждый размером примерно в 1 024 000 байт.

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

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

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

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

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

Как закрыть Logger

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

не используется после 1.2.7. только для совместимости.

Константы

ProgName
SEV_LABEL

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

VERSION

Атрибуты

formatter[RW]

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

severity

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

time

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

progname

progname, настроенный или переданный методу Logger.

msg

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

Блок должен возвращать Object, который может быть записан в устройство ведения лога с помощью 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 380
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 != File::NULL
    @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, или открытый файл), nil (ничего не записывает) или File::NULL (то же, что nil).

shift_age

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

shift_size

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

level

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

progname

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

formatter

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

datetime_format

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

binmode

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

shift_period_suffix

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

Описание

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

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

<<(msg) Show source
# File lib/logger.rb, line 485
def <<(msg)
  @logdev&.write(msg)
end

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

Logger#add(severity, message = nil, progname = nil) { ... } Show source
# File lib/logger.rb, line 459
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

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

progname

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

block

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

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

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

Описание

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

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

Ошибки

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

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

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

Также имеет псевдоним: log
close() Show source
# File lib/logger.rb, line 572
def close
  @logdev&.close
end

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

datetime_format() Show source
# File lib/logger.rb, line 284
def datetime_format
  @default_formatter.datetime_format
end

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

datetime_format=(datetime_format) Show source
# 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) Show source
# File lib/logger.rb, line 494
def debug(progname = nil, &block)
  add(DEBUG, nil, progname, &block)
end

Зарегистрировать сообщение DEBUG.

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

debug!() Show source
# File lib/logger.rb, line 310
def debug!; self.level = DEBUG; end

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

debug?() Show source
# File lib/logger.rb, line 307
def debug?; level <= DEBUG; end

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

error(progname = nil, &block) Show source
# File lib/logger.rb, line 546
def error(progname = nil, &block)
  add(ERROR, nil, progname, &block)
end

Зарегистрировать сообщение ERROR.

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

error!() Show source
# File lib/logger.rb, line 331
def error!; self.level = ERROR; end

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

error?() Show source
# File lib/logger.rb, line 328
def error?; level <= ERROR; end

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

fatal(progname = nil, &block) Show source
# File lib/logger.rb, line 555
def fatal(progname = nil, &block)
  add(FATAL, nil, progname, &block)
end

Зарегистрировать сообщение FATAL.

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

fatal!() Show source
# File lib/logger.rb, line 338
def fatal!; self.level = FATAL; end

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

fatal?() Show source
# File lib/logger.rb, line 335
def fatal?; level <= FATAL; end

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

info(message) Show source
info(progname, &block)
# File lib/logger.rb, line 528
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!() Show source
# File lib/logger.rb, line 317
def info!; self.level = INFO; end

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

info?() Show source
# 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

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

Также известно как: sev_threshold=
Logger#add(severity, message = nil, progname = nil) { ... }
Псевдоним для: add
Logger#reopen Показать исходный код
Logger#reopen(logdev)
# File lib/logger.rb, line 413
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 565
def unknown(progname = nil, &block)
  add(UNKNOWN, nil, progname, &block)
end

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

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

warn(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 537
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 585
def format_message(severity, datetime, progname, msg)
  (@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
format_severity(severity) Показать исходный код
# File lib/logger.rb, line 581
def format_severity(severity)
  SEV_LABEL[severity] || 'ANY'
end

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

Spec-Zone.ru

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