類別 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')
當您呼叫這些方法中的任何一個時,項目可能會寫入記錄,也可能不會,這取決於項目的嚴重性以及記錄層級;請參閱 記錄層級
項目永遠有
-
嚴重性(
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
ID。 -
嚴重性(字詞)。
-
程式名稱。
-
訊息。
您可以透過下列方式使用不同的條目格式
-
設定自訂格式 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
為 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\\\""
要包含在日誌訊息中的程式名稱。
公開類別方法
使用單一引數 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'
。請參閱 定期輪替。
# 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
寫入記錄中,不進行格式化;傳回寫入的字元數,或如果沒有記錄裝置,則傳回 nil
logger = Logger.new($stdout) logger << 'My message.' # => 10
輸出
My message.
# File lib/logger.rb, line 684 def <<(msg) @logdev&.write(msg) 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
這些方便的方法具有隱含的嚴重性
# 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
關閉記錄器;傳回 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=
。
# File lib/logger.rb, line 438 def datetime_format @default_formatter.datetime_format end
設定日期時間格式。
參數 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
等於呼叫 add
,其中嚴重性為 Logger::DEBUG
。
# File lib/logger.rb, line 690 def debug(progname = nil, &block) add(DEBUG, nil, progname, &block) end
將記錄等級設定為 Logger::DEBUG。請參閱 記錄等級。
# File lib/logger.rb, line 487 def debug!; self.level = DEBUG; end
如果記錄等級允許寫入嚴重性為 Logger::DEBUG 的項目,則傳回 true
,否則傳回 false
。請參閱 記錄等級。
# File lib/logger.rb, line 482 def debug?; level <= DEBUG; end
等於呼叫 add
,其中嚴重性為 Logger::ERROR
。
# File lib/logger.rb, line 708 def error(progname = nil, &block) add(ERROR, nil, progname, &block) end
將記錄等級設定為 Logger::ERROR。請參閱 記錄等級。
# File lib/logger.rb, line 520 def error!; self.level = ERROR; end
如果記錄等級允許寫入嚴重性為 Logger::ERROR 的項目,則傳回 true
,否則傳回 false
。請參閱 記錄等級。
# File lib/logger.rb, line 515 def error?; level <= ERROR; end
等於呼叫 add
,其中嚴重性為 Logger::FATAL
。
# File lib/logger.rb, line 714 def fatal(progname = nil, &block) add(FATAL, nil, progname, &block) end
將記錄等級設定為 Logger::FATAL。請參閱 記錄等級。
# File lib/logger.rb, line 531 def fatal!; self.level = FATAL; end
如果記錄等級允許寫入嚴重性為 Logger::FATAL 的項目,則傳回 true
,否則傳回 false
。請參閱 記錄等級。
# File lib/logger.rb, line 526 def fatal?; level <= FATAL; end
等同於呼叫 add
,並設定嚴重性為 Logger::INFO
。
# File lib/logger.rb, line 696 def info(progname = nil, &block) add(INFO, nil, progname, &block) end
將記錄等級設定為 Logger::INFO。請參閱 記錄等級。
# File lib/logger.rb, line 498 def info!; self.level = INFO; end
如果記錄等級允許寫入嚴重性為 Logger::INFO 的項目,則傳回 true
,否則傳回 false
。請參閱 記錄等級。
# File lib/logger.rb, line 493 def info?; level <= INFO; end
記錄嚴重性閾值(例如 Logger::INFO
)。
# File lib/logger.rb, line 383 def level @level_override[Fiber.current] || @level 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=
的別名。
# File lib/logger.rb, line 399 def level=(severity) @level = Severity.coerce(severity) 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"]
# File lib/logger.rb, line 619 def reopen(logdev = nil) @logdev&.reopen(logdev) self end
等同於呼叫 add
,並設定嚴重性為 Logger::UNKNOWN
。
# File lib/logger.rb, line 720 def unknown(progname = nil, &block) add(UNKNOWN, nil, progname, &block) end
等同於呼叫 add
,嚴重性為 Logger::WARN
。
# File lib/logger.rb, line 702 def warn(progname = nil, &block) add(WARN, nil, progname, &block) end
將記錄層級設定為 Logger::WARN。請參閱 記錄層級。
# File lib/logger.rb, line 509 def warn!; self.level = WARN; end
如果記錄層級允許寫入嚴重性為 Logger::WARN 的項目,則傳回 true
,否則傳回 false
。請參閱 記錄層級。
# File lib/logger.rb, line 504 def warn?; level <= WARN; end
僅針對目前的 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
私人執行個體方法
# File lib/logger.rb, line 744 def format_message(severity, datetime, progname, msg) (@formatter || @default_formatter).call(severity, datetime, progname, msg) end
# File lib/logger.rb, line 740 def format_severity(severity) SEV_LABEL[severity] || 'ANY' end