類別 Logger

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')

當您呼叫這些方法中的任何一個時,項目可能會寫入記錄,也可能不會,這取決於項目的嚴重性以及記錄層級;請參閱 記錄層級

項目永遠有

也可能會有

範例

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"

其中要格式化的值為

您可以透過下列方式使用不同的條目格式

嚴重性

記錄條目的嚴重性有兩個影響

時間戳記

記錄條目的時間戳記會在建立條目時自動產生。

記錄的時間戳記會使用此格式字串,由方法 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,訊息物件可能是

注意: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

範例

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 已滿,日誌檔案會輪替

定期輪替

對於定期輪替,請使用字串週期指標呼叫 Logger.new

範例

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')

當給定的週期到期時

字尾的預設格式為 '%Y%m%d',會產生類似於上述的字尾。您可以使用建立時間選項 shift_period_suffix 設定不同的格式;請參閱 Time#strftime 中的詳細資料和建議。

常數

ProgName
SEV_LABEL

記錄的嚴重性標籤(最多 5 個字元)。

VERSION

屬性

formatter[RW]

設定或擷取記錄器條目格式化器程序。

formatternil 時,記錄器會使用 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\\\""
progname[RW]

要包含在日誌訊息中的程式名稱。

公開類別方法

new(logdev, shift_age = 0, shift_size = 1048576, **options) 按一下以切換來源

使用單一引數 logdev,傳回具有所有預設選項的新記錄器

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

參數 logdev 必須為下列之一

  • 字串檔案路徑:項目將寫入該路徑的檔案中;如果該路徑的檔案存在,新的項目將附加在後面。

  • 一個 IO 串流(通常是 +$stdout+、+$stderr+ 或一個開啟的檔案):項目將寫入指定的串流中。

  • nilFile::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'。請參閱 定期輪替

# File lib/logger.rb, line 578
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
  @level_override = {}
  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

公開執行個體方法

<<(msg) 按一下以切換來源

將指定的 msg 寫入記錄中,不進行格式化;傳回寫入的字元數,或如果沒有記錄裝置,則傳回 nil

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

輸出

My message.
# File lib/logger.rb, line 684
def <<(msg)
  @logdev&.write(msg)
end
add(severity, message = nil, progname = nil) { || ... } 按一下以切換來源

建立記錄項目,可能會寫入記錄中,具體取決於項目的嚴重性和記錄層級。有關詳細資訊,請參閱 記錄層級項目

範例

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

這些方便的方法具有隱含的嚴重性

# File lib/logger.rb, line 651
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
別名為: log
close() 按一下以切換來源

關閉記錄器;傳回 nil

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

相關: Logger#reopen

# File lib/logger.rb, line 731
def close
  @logdev&.close
end
datetime_format() 按一下以切換來源

傳回日期時間格式;請參閱 datetime_format=

# File lib/logger.rb, line 438
def datetime_format
  @default_formatter.datetime_format
end
datetime_format=(datetime_format) 按一下以切換來源

設定日期時間格式。

參數 datetime_format 應為下列其中之一

  • 適用於方法 Time#strftime 格式的字串。

  • nil:記錄器使用 '%Y-%m-%dT%H:%M:%S.%6N'

# File lib/logger.rb, line 432
def datetime_format=(datetime_format)
  @default_formatter.datetime_format = datetime_format
end
debug(progname = nil, &block) 按一下以切換來源

等於呼叫 add,其中嚴重性為 Logger::DEBUG

# File lib/logger.rb, line 690
def debug(progname = nil, &block)
  add(DEBUG, nil, progname, &block)
end
debug!() 按一下以切換來源

將記錄等級設定為 Logger::DEBUG。請參閱 記錄等級

# File lib/logger.rb, line 487
def debug!; self.level = DEBUG; end
debug?() 按一下以切換來源

如果記錄等級允許寫入嚴重性為 Logger::DEBUG 的項目,則傳回 true,否則傳回 false。請參閱 記錄等級

# File lib/logger.rb, line 482
def debug?; level <= DEBUG; end
error(progname = nil, &block) 按一下以切換來源

等於呼叫 add,其中嚴重性為 Logger::ERROR

# File lib/logger.rb, line 708
def error(progname = nil, &block)
  add(ERROR, nil, progname, &block)
end
error!() 按一下以切換來源

將記錄等級設定為 Logger::ERROR。請參閱 記錄等級

# File lib/logger.rb, line 520
def error!; self.level = ERROR; end
error?() 按一下以切換來源

如果記錄等級允許寫入嚴重性為 Logger::ERROR 的項目,則傳回 true,否則傳回 false。請參閱 記錄等級

# File lib/logger.rb, line 515
def error?; level <= ERROR; end
fatal(progname = nil, &block) 按一下以切換來源

等於呼叫 add,其中嚴重性為 Logger::FATAL

# File lib/logger.rb, line 714
def fatal(progname = nil, &block)
  add(FATAL, nil, progname, &block)
end
fatal!() 按一下以切換來源

將記錄等級設定為 Logger::FATAL。請參閱 記錄等級

# File lib/logger.rb, line 531
def fatal!; self.level = FATAL; end
fatal?() 按一下以切換來源

如果記錄等級允許寫入嚴重性為 Logger::FATAL 的項目,則傳回 true,否則傳回 false。請參閱 記錄等級

# File lib/logger.rb, line 526
def fatal?; level <= FATAL; end
info(progname = nil, &block) 按一下以切換來源

等同於呼叫 add,並設定嚴重性為 Logger::INFO

# File lib/logger.rb, line 696
def info(progname = nil, &block)
  add(INFO, nil, progname, &block)
end
info!() 按一下以切換來源

將記錄等級設定為 Logger::INFO。請參閱 記錄等級

# File lib/logger.rb, line 498
def info!; self.level = INFO; end
info?() 按一下以切換來源

如果記錄等級允許寫入嚴重性為 Logger::INFO 的項目,則傳回 true,否則傳回 false。請參閱 記錄等級

# File lib/logger.rb, line 493
def info?; level <= INFO; end
level() 按一下以切換來源

記錄嚴重性閾值(例如 Logger::INFO)。

# File lib/logger.rb, line 383
def level
  @level_override[Fiber.current] || @level
end
別名為:sev_threshold
level=(severity) 按一下以切換來源

設定記錄等級;傳回 severity。請參閱 記錄等級

引數 severity 可以是整數、字串或符號

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

Logger#sev_threshold=Logger#level= 的別名。

# File lib/logger.rb, line 399
def level=(severity)
  @level = Severity.coerce(severity)
end
別名為:sev_threshold=
log(severity, message = nil, progname = nil)
別名為:add
reopen(logdev = nil) 按一下以切換來源

設定記錄器的輸出串流

  • 如果 logdevnil,則重新開啟目前的輸出串流。

  • 如果 logdev 為檔案路徑,則開啟指定的檔案以附加。

  • 如果 logdevIO 串流(通常為 $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"]
# File lib/logger.rb, line 619
def reopen(logdev = nil)
  @logdev&.reopen(logdev)
  self
end
sev_threshold()
別名為:level
sev_threshold=(severity)
別名為:level=
unknown(progname = nil, &block) 按一下以切換來源

等同於呼叫 add,並設定嚴重性為 Logger::UNKNOWN

# File lib/logger.rb, line 720
def unknown(progname = nil, &block)
  add(UNKNOWN, nil, progname, &block)
end
warn(progname = nil, &block) 按一下以切換來源

等同於呼叫 add,嚴重性為 Logger::WARN

# File lib/logger.rb, line 702
def warn(progname = nil, &block)
  add(WARN, nil, progname, &block)
end
warn!() 按一下以切換來源

將記錄層級設定為 Logger::WARN。請參閱 記錄層級

# File lib/logger.rb, line 509
def warn!; self.level = WARN; end
warn?() 按一下以切換來源

如果記錄層級允許寫入嚴重性為 Logger::WARN 的項目,則傳回 true,否則傳回 false。請參閱 記錄層級

# File lib/logger.rb, line 504
def warn?; level <= WARN; end
with_level(severity) { || ... } 按一下以切換來源

僅針對目前的 Fiber 調整區塊執行期間的記錄層級

logger.with_level(:debug) do
  logger.debug { "Hello" }
end
# File lib/logger.rb, line 408
def with_level(severity)
  prev, @level_override[Fiber.current] = level, Severity.coerce(severity)
  begin
    yield
  ensure
    if prev
      @level_override[Fiber.current] = prev
    else
      @level_override.delete(Fiber.current)
    end
  end
end

私人執行個體方法

format_message(severity, datetime, progname, msg) 按一下以切換來源
# File lib/logger.rb, line 744
def format_message(severity, datetime, progname, msg)
  (@formatter || @default_formatter).call(severity, datetime, progname, msg)
end
format_severity(severity) 按一下以切換來源
# File lib/logger.rb, line 740
def format_severity(severity)
  SEV_LABEL[severity] || 'ANY'
end