什么是Handler?
Handler instances dispatch logging events to specific destinations.
其實(shí)很簡(jiǎn)單, Handler決定了你的LogRecord
最終出現(xiàn)的位置, 你的log信息是直接輸出到終端(StreamHandler) 還是 保存到 log文件(FileHandler).
Handler是如何記錄信息的?
常見(jiàn)的Handler就是我們常用的I/O操作, 類似于我們的print()
以及file.write()
, 以StreamHandler
為例:
class StreamHandler(Handler):
terminator = '\n'
def __init__(self, stream=None):
"""
Initialize the handler.
If stream is not specified, sys.stderr is used.
"""
Handler.__init__(self)
if stream is None:
stream = sys.stderr
self.stream = stream
def emit(self, record):
"""
Emit a record.
"""
try:
msg = self.format(record)
stream = self.stream
stream.write(msg)
stream.write(self.terminator)
self.flush()
except Exception:
self.handleError(record)
log消息的輸出是用emit()
函數(shù)實(shí)現(xiàn)的, 本質(zhì)就是sys.stderr.write()
, 這樣一看logging
模塊就非常簡(jiǎn)單了.
然后我們?cè)倏匆幌翭ileHandler的 emit()
:
class FileHandler(StreamHandler):
"""
A handler class which writes formatted logging records to disk files.
"""
def __init__(self, filename, mode='a', encoding=None, delay=False):
if delay:
#We don't open the stream, but we still need to call the
#Handler constructor to set level, formatter, lock etc.
Handler.__init__(self)
self.stream = None
else:
StreamHandler.__init__(self, self._open())
def emit(self, record):
"""
Emit a record.
"""
if self.stream is None:
self.stream = self._open()
StreamHandler.emit(self, record)
FileHandler
繼承自StreamHandler
, 只是把stream
替換為打開(kāi)的文件, 所以我們的emit
就變?yōu)榱?code>file.write().
flush()
是做什么用的?
The internal buffers are buffers created by the runtime/library/language that you're programming against and is meant to speed things up by avoiding system calls for every write. Instead, when you write to a file object, you write into its buffer, and whenever the buffer fills up, the data is written to the actual file using system calls.
當(dāng)我們讀寫文件, 類似stdout
或者是打開(kāi)的文件, 我們的數(shù)據(jù)都在緩存中, flush
保證將緩存中的數(shù)據(jù)寫入文件, 這個(gè)操作一般在文件close()
時(shí)自動(dòng)執(zhí)行.
Thread Safe
類似于讀寫文件的操作是位于臨界區(qū)內(nèi), 多個(gè)線程同時(shí)操作會(huì)導(dǎo)致race condition
, 所以在讀寫文件操作時(shí), logging
模塊對(duì)這些操作進(jìn)行了加鎖:
def flush(self):
"""
Flushes the stream.
"""
self.acquire()
try:
if self.stream and hasattr(self.stream, "flush"):
self.stream.flush()
finally:
self.release()
總結(jié)
Handler
作為logging
模塊中最常用的class
之一, 通過(guò)了解其實(shí)現(xiàn), 能夠更好的幫助我們理解logging
模塊.