Spec-Zone.ru › Ruby 3.2

класс Logger

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

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

О примерах

Все примеры на этой странице предполагают, что Logger был загружен:

require 'logger'

Краткое описание

Создайте журнал с помощью Logger.new:

# Single log file.
logger = Logger.new('t.log')
# Size-based rotated logging: 3 10-megabyte files.
logger = Logger.new('t.log', 3, 10485760)
# Period-based rotated logging: daily (also allowed: 'weekly', 'monthly').
logger = Logger.new('t.log', 'daily')
# Log to an IO stream.
logger = Logger.new($stdout)

Добавьте записи (уровень, сообщение) с помощью Logger#add:

logger.add(Logger::DEBUG, 'Maximal debugging info')
logger.add(Logger::INFO, 'Non-error information')
logger.add(Logger::WARN, 'Non-error warning')
logger.add(Logger::ERROR, 'Non-fatal error')
logger.add(Logger::FATAL, 'Fatal error')
logger.add(Logger::UNKNOWN, 'Most severe')

Закройте журнал с помощью Logger#close:

logger.close

Записи

Вы можете добавить записи с помощью метода Logger#add:

logger.add(Logger::DEBUG, 'Maximal debugging info')
logger.add(Logger::INFO, 'Non-error information')
logger.add(Logger::WARN, 'Non-error warning')
logger.add(Logger::ERROR, 'Non-fatal error')
logger.add(Logger::FATAL, 'Fatal error')
logger.add(Logger::UNKNOWN, 'Most severe')

Эти сокращенные методы также добавляют записи:

logger.debug('Maximal debugging info')
logger.info('Non-error information')
logger.warn('Non-error warning')
logger.error('Non-fatal error')
logger.fatal('Fatal error')
logger.unknown('Most severe')

Когда вы вызываете любой из этих методов, запись может или не может быть записана в журнал, в зависимости от уровня серьезности записи и уровня журнала; см. Уровень журнала

Запись всегда имеет:

  • Уровень серьезности (обязательный аргумент для add).

  • Автоматически созданную метку времени.

И также может иметь:

  • Сообщение.

  • Имя программы.

Пример:

logger = Logger.new($stdout)
logger.add(Logger::INFO, 'My message.', 'mung')
# => I, [2022-05-07T17:21:46.536234 #20536]  INFO -- mung: My message.

Формат записи по умолчанию:

"%s, [%s #%d] %5s -- %s: %s\n"

где значения для форматирования:

  • Уровень серьезности (одна буква).

  • Метка времени.

  • Process идентификатор.

  • Уровень серьезности (слово).

  • Имя программы.

  • Сообщение.

Вы можете использовать другой формат записи, выполнив:

  • Установка пользовательского формата proc (сказывается на последующих записях); см. formatter=.

  • Вызов любого из вышеуказанных методов с блоком (сказывается только на одной записи). Это может иметь две выгоды:

    • Контекст: блок может оценить весь контекст программы и создать сообщение, зависящее от контекста.

    • Производительность: блок не оценивается, если уровень журнала не разрешает фактическое запись записи:

      logger.error { my_slow_message_generator }
      

      Протипоставьте это строковой форме, где строка всегда оценивается, независимо от уровня журнала:

      logger.error("#{my_slow_message_generator}")
      

Уровень серьезности

Уровень серьезности записи журнала имеет два эффекта:

  • Определяет, выбирается ли запись для включения в журнал; см. Уровень журнала.

  • Указывает любому читателю журнала (будь то человек или программа) относительную важность записи.

Метка времени

Метка времени записи журнала генерируется автоматически при создании записи.

Записанная метка времени форматируется методом Time#strftime с использованием следующего формата:

'%Y-%m-%dT%H:%M:%S.%6N'

Пример:

logger = Logger.new($stdout)
logger.add(Logger::INFO)
# => I, [2022-05-07T17:04:32.318331 #20536]  INFO -- : nil

Вы можете установить другой формат, используя метод datetime_format=.

Сообщение

Сообщение является необязательным аргументом метода записи:

logger = Logger.new($stdout)
logger.add(Logger::INFO, 'My message')
# => I, [2022-05-07T18:15:37.647581 #20536]  INFO -- : My message

Для формата записи по умолчанию, Logger::Formatter, объект сообщения может быть:

  • Строка: используется как есть.

  • Исключение: message.message используется.

  • Что-либо другое: message.inspect используется.

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

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

Имя программы

Имя программы является необязательным аргументом метода записи:

logger = Logger.new($stdout)
logger.add(Logger::INFO, 'My message', 'mung')
# => I, [2022-05-07T18:17:38.084716 #20536]  INFO -- mung: My message

Имя программы по умолчанию для нового логгера может быть установлено в вызове Logger.new через необязательный ключевой аргумент progname:

logger = Logger.new('t.log', progname: 'mung')

Имя программы по умолчанию для существующего логгера может быть установлено вызовом метода progname=:

logger.progname = 'mung'

Текущее имя программы можно получить с помощью метода progname:

logger.progname # => "mung"

Уровень журнала

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

Определенные уровни серьезности (от наименее серьезного к наиболее серьезному):

logger = Logger.new($stdout)
logger.add(Logger::DEBUG, 'Maximal debugging info')
# => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info
logger.add(Logger::INFO, 'Non-error information')
# => I, [2022-05-07T17:59:14.349167 #20536]  INFO -- : Non-error information
logger.add(Logger::WARN, 'Non-error warning')
# => W, [2022-05-07T18:00:45.337538 #20536]  WARN -- : Non-error warning
logger.add(Logger::ERROR, 'Non-fatal error')
# => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error
logger.add(Logger::FATAL, 'Fatal error')
# => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error
logger.add(Logger::UNKNOWN, 'Most severe')
# => A, [2022-05-07T18:07:54.657491 #20536]   ANY -- : Most severe

Настройка уровня по умолчанию — Logger::DEBUG, наименьший уровень, что означает, что все записи должны быть записаны независимо от уровня серьезности:

logger = Logger.new($stdout)
logger.level # => 0
logger.add(0, "My message")
# => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message

Вы можете указать другую настройку в новом логгере, используя ключевой аргумент level с соответствующим значением:

logger = Logger.new($stdout, level: Logger::ERROR)
logger = Logger.new($stdout, level: 'error')
logger = Logger.new($stdout, level: :error)
logger.level # => 3

С этим уровнем записи с уровнем серьезности Logger::ERROR и выше записываются, а те с более низкими уровнями серьезности не записываются:

logger = Logger.new($stdout, level: Logger::ERROR)
logger.add(3)
# => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil
logger.add(2) # Silent.

Вы можете установить уровень журнала для существующего логгера с помощью метода level=:

logger.level = Logger::ERROR

Эти сокращенные методы также устанавливают уровень:

logger.debug! # => 0
logger.info!  # => 1
logger.warn!  # => 2
logger.error! # => 3
logger.fatal! # => 4

Вы можете получить уровень журнала с помощью метода level:

logger.level = Logger::ERROR
logger.level # => 3

Эти методы возвращают, нужно ли писать данный уровень:

logger.level = Logger::ERROR
logger.debug? # => false
logger.info?  # => false
logger.warn?  # => false
logger.error? # => true
logger.fatal? # => true

Вращение журнала File

По умолчанию файл журнала — это один файл, который неограниченно растет (пока не закрыт явно); вращения файлов нет.

Чтобы сохранить файлы журнала в управляемых размерах, можно использовать вращение файлов журнала, которое использует несколько файлов журнала:

  • Каждый файл журнала содержит записи за неперекрываемый временной интервал.

  • Только самый последний файл журнала открыт и активен; остальные закрыты и неактивны.

Вращение по размеру

Для вращения журнала по размеру вызовите Logger.new с:

  • Аргументом logdev в качестве пути к файлу.

  • Аргументом shift_age с положительным целым числом: количество файлов журнала для вращения.

  • Аргументом shift_size в качестве положительного целого числа: максимальный размер (в байтах) каждого файла журнала; по умолчанию 1048576 (1 мегабайт).

Примеры:

logger = Logger.new('t.log', 3)           # Three 1-megabyte files.
logger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files.

Для этих примеров предположим:

logger = Logger.new('t.log', 3)

Ведение журнала начинается в новом файле журнала, t.log; файл журнала «полный» и готов к вращению, когда новая запись приведет к превышению размера shift_size.

В первый раз, когда t.log заполнен:

  • t.log закрывается и переименовывается в t.log.0.

  • Открывается новый файл t.log.

Во второй раз, когда t.log заполнен:

  • +t.log.0 переименовывается в t.log.1.

  • t.log закрывается и переименовывается в t.log.0.

  • Открывается новый файл t.log.

Каждый последующий раз, когда t.log заполнен, файлы журнала вращаются:

  • t.log.1 удаляется.

  • +t.log.0 переименовывается в t.log.1.

  • t.log закрывается и переименовывается в t.log.0.

  • Открывается новый файл t.log.

Периодическое вращение

Для периодического вращения вызовите Logger.new с:

  • Аргументом logdev в качестве пути к файлу.

  • Аргументом shift_age в качестве строки-индикатора периода.

Примеры:

logger = Logger.new('t.log', 'daily')   # Rotate log files daily.
logger = Logger.new('t.log', 'weekly')  # Rotate log files weekly.
logger = Logger.new('t.log', 'monthly') # Rotate log files monthly.

Пример:

logger = Logger.new('t.log', 'daily')

Когда истекает указанный период:

  • Базовый файл журнала, t.log закрывается и переименовывается с датой-базированным суффиксом, таким как t.log.20220509.

  • Открывается новый файл журнала t.log.

  • Ничего не удаляется.

Формат суффикса по умолчанию — '%Y%m%d', который создаёт суффикс, аналогичный приведенному выше. Вы можете установить другой формат с помощью опции создания времени shift_period_suffix; см. детали и рекомендации в Time#strftime.

Константы

ProgName
SEV_LABEL

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

VERSION

Атрибуты

formatter[RW]

Устанавливает или извлекает процедуру форматирования записи логгера.

Когда formatter равно nil, логгер использует Logger::Formatter.

Когда formatter является процедурой, новая запись форматируется этой процедурой, которая вызывается с четырьмя аргументами:

  • severity: Уровень серьезности записи.

  • time: Объект Time, представляющий временную метку записи.

  • progname: Имя программы для записи.

  • msg: Сообщение для записи (строка или объект, преобразуемый в строку).

Процедура должна вернуть строку, содержащую отформатированную запись.

Этот пользовательский форматировщик использует String#dump для экранирования строки сообщения:

logger = Logger.new($stdout, progname: 'mung')
original_formatter = logger.formatter || Logger::Formatter.new
logger.formatter = proc { |severity, time, progname, msg|
  original_formatter.call(severity, time, progname, msg.dump)
}
logger.add(Logger::INFO, "hello \n ''")
logger.add(Logger::INFO, "\f\x00\xff\\\"")

Вывод:

I, [2022-05-13T13:16:29.637488 #8492]  INFO -- mung: "hello \n ''"
I, [2022-05-13T13:16:29.637610 #8492]  INFO -- mung: "\f\x00\xFF\\\""
level[R]

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

progname[RW]

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

sev_threshold[R]

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

Методы публичного класса

new(logdev, shift_age = 0, shift_size = 1048576, **options) Показать исходный код
# File lib/logger.rb, line 577
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, возвращает новый логгер со всеми значениями по умолчанию:

Logger.new('t.log') # => #<Logger:0x000001e685dc6ac8>

Аргумент logdev должен быть одним из:

  • Путь к файлу в виде строки: записи будут записываться в файл по этому пути; если файл по этому пути существует, новые записи будут добавлены.

  • Поток IO (обычно +$stdout+, +$stderr+ или открытый файл): записи будут записываться в указанный поток.

  • nil или File::NULL: записи не будут записываться.

Примеры:

Logger.new('t.log')
Logger.new($stdout)

Ключевые параметры:

  • level: устанавливает уровень журнала; значение по умолчанию — Logger::DEBUG. См. Уровень журнала:

    Logger.new('t.log', level: Logger::ERROR)
    
  • progname: устанавливает имя программы по умолчанию; значение по умолчанию — nil. См. Имя программы:

    Logger.new('t.log', progname: 'mung')
    
  • formatter: устанавливает форматировщик записей; значение по умолчанию — nil. См. formatter=.

  • datetime_format: устанавливает формат временной метки записи; значение по умолчанию — nil. См. datetime_format=.

  • binmode: устанавливает, записывать ли логгер в двоичном режиме; значение по умолчанию — false.

  • shift_period_suffix: устанавливает формат суффикса имени файла для периодической ротации файла журнала; значение по умолчанию — '%Y%m%d'. См. Периодическая ротация.

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

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

Записывает заданный msg в лог без форматирования; возвращает количество записанных символов или nil если устройство логирования отсутствует:

logger = Logger.new($stdout)
logger << 'My message.' # => 10

Вывод:

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

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

Примеры:

logger = Logger.new($stdout, progname: 'mung')
logger.add(Logger::INFO)
logger.add(Logger::ERROR, 'No good')
logger.add(Logger::ERROR, 'No good', 'gnum')

Вывод:

I, [2022-05-12T16:25:31.469726 #36328]  INFO -- mung: mung
E, [2022-05-12T16:25:55.349414 #36328] ERROR -- mung: No good
E, [2022-05-12T16:26:35.841134 #36328] ERROR -- gnum: No good

Эти вспомогательные методы имеют неявную серьезность:

  • debug.

  • info.

  • warn.

  • error.

  • fatal.

  • unknown.

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

Закрывает средство логирования; возвращает nil:

logger = Logger.new('t.log')
logger.close       # => nil
logger.info('foo') # Prints "log writing failed. closed stream"

Связанный метод: Logger#reopen.

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

Возвращает формат даты и времени; см. datetime_format=.

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

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

Аргумент datetime_format должен быть одним из следующих:

  • Строка, подходящая для использования в качестве формата для метода Time#strftime.

  • nil: средство логирования использует '%Y-%m-%dT%H:%M:%S.%6N'.

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

Эквивалентно вызову add с серьезностью Logger::DEBUG.

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

Устанавливает уровень логирования на Logger::DEBUG. См. Уровень логирования.

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

Возвращает true если уровень логирования позволяет записывать записи с серьезностью Logger::DEBUG, false в противном случае. См. Уровень логирования.

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

Эквивалентно вызову add с серьезностью Logger::ERROR.

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

Устанавливает уровень логирования на Logger::ERROR. См. Уровень логирования.

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

Возвращает true если уровень логирования позволяет записывать записи с серьезностью Logger::ERROR, false в противном случае. См. Уровень логирования.

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

Эквивалентно вызову add с серьезностью Logger::FATAL.

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

Устанавливает уровень логирования на Logger::FATAL. См. Уровень логирования.

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

Возвращает true если уровень логирования позволяет записывать записи с серьезностью Logger::FATAL, false в противном случае. См. Уровень логирования.

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

Эквивалентно вызову add с серьезностью Logger::INFO.

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

Устанавливает уровень логирования на Logger::INFO. См. Уровень логирования.

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

Возвращает true если уровень логирования позволяет записывать записи с серьезностью Logger::INFO, false в противном случае. См. Уровень логирования.

level=(severity) Показать исходный код
# File lib/logger.rb, line 397
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 может быть целым числом, строкой или символом:

logger.level = Logger::ERROR # => 3
logger.level = 3             # => 3
logger.level = 'error'       # => "error"
logger.level = :error        # => :error

Logger#sev_threshold= является псевдонимом для Logger#level=.

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

Устанавливает поток вывода для регистрации:

  • Если logdev является nil, повторно открывает текущий поток вывода.

  • Если logdev является путем к файлу, открывает указанный файл для добавления.

  • Если logdev является потоком IO (обычно $stdout, $stderr, или открытый объект File), открывает поток для добавления.

Пример:

logger = Logger.new('t.log')
logger.add(Logger::ERROR, 'one')
logger.close
logger.add(Logger::ERROR, 'two') # Prints 'log writing failed. closed stream'
logger.reopen
logger.add(Logger::ERROR, 'three')
logger.close
File.readlines('t.log')
# =>
# ["# Logfile created on 2022-05-12 14:21:19 -0500 by logger.rb/v1.5.0\n",
#  "E, [2022-05-12T14:21:27.596726 #22428] ERROR -- : one\n",
#  "E, [2022-05-12T14:23:05.847241 #22428] ERROR -- : three\n"]
sev_threshold=(severity)
Псевдоним для: level=
unknown(progname = nil, &block) Показать исходный код
# File lib/logger.rb, line 718
def unknown(progname = nil, &block)
  add(UNKNOWN, nil, progname, &block)
end

Эквивалентно вызову add с уровнем серьезности Logger::UNKNOWN.

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

Эквивалентно вызову add с уровнем серьезности Logger::WARN.

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

Устанавливает уровень регистрации в Logger::WARN. См. Уровень лога.

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

Возвращает true, если уровень регистрации разрешает записи с уровнем серьезности Logger::WARN, false в противном случае. См. Уровень лога.

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

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