Spec-Zone.ru › Ruby 2.6

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

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

Константы

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 377
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 481
def <<(msg)
  @logdev&.write(msg)
end

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

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

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

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

Описание

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

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

Ошибки

  • Файл логов не блокируется.

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

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

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

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

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

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

datetime_format=(datetime_format) Показать исходный код
# File lib/logger.rb, line 295
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 490
def debug(progname = nil, &block)
  add(DEBUG, nil, progname, &block)
end

Зарегистрировать сообщение уровня отладки.

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

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

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

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

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

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

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

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

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

Зарегистрировать критически важное сообщение.

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

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

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

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

Зарегистрировать сообщение информационного уровня.

message

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

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

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

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

Set порог степени важности регистрации.

severity

Степень важности Severity сообщения.

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

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

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

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

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

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

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

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

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

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