pythonノート_loggingモジュール(一)
9384 ワード
loggingモジュールはpythonでよく使われるモジュールで、このモジュールの使い方を2~3つの文章で詳しく紹介する予定です.最初の文章は主にloggingのメインソースを話して、もし直接loggingの使い方を見たいならば、第2編を待つことができます.
参照するloggingバージョンはpython 2です.7.3、私はloggingソースコードに中国語の注釈を加えて私のgithubに置いた.https://github.com/Stan-He/python_learn/tree/master/learn_logging
1.開始
最初は、loggingの基本機能を最短のコードで体験してみましょう最初のステップはloggingを通過する.getLoger関数は、logerオブジェクトを取得しますが、このオブジェクトは一時的に使用できません. 第2ステップ、logging.basicConfig関数は、format、handlerなど、デフォルトの構成を行います. ステップ3、loger呼び出しsetLevel関数定義ログレベルDEBUG 最後に、loggerはdebug関数を呼び出し、標準出力 に表示されるdebugレベルのmessageを出力する.
2.loggingのログ・レベル
loggingはログを生成する際に、ログ・レベルのメカニズムがあり、デフォルトでは以下のログ・レベルがあります.
各loggerオブジェクトには、levelより高いログのみを出力するログ・レベルがあります.loggerのレベルがINFOの場合、loggerが呼び出されます.debug()はログを出力できませんが、logger.warning()は出力できます.
一般的に、以上の6つのログ・レベルは、私たちの日常的な使用を完全に満たしています.
3.loggingのベースクラス
loggingはpythonのベースモジュールであり、pythonのソースコードの位置は以下の通りです.
ロゴを構成する主幹のいくつかの基礎クラスはすべて__にありますinit__.py:
3.1最初の基礎クラスLogRecord
ログ内の1行のデータに対応するLogRecordオブジェクト.通常は、時間、ログ・レベル、メッセージ情報、現在実行されているモジュール、行番号、関数名などが含まれます.これらの情報は、LogRecordオブジェクトに含まれます.LogRecordオブジェクトは大きな辞書として想像できます
3.2 2番目の基礎クラスFormatter
Formatterオブジェクトはログフォーマットを定義するために使用され、LogRecordは多くの情報を保存していますが、ログを打つときにいくつかしか必要ありません.Formatterはpythonの機能に依存する機能を提供しています.
LogRecordが後の辞書なら、Formatterは前のフォーマット文字列・・・の抽象です
重要なコードは次のとおりです.
3.3 3番目のベースクラスFilterとFilterer
Filterクラス、機能は簡単です.Flter.フィルタ()関数はLogRecordオブジェクトを入力し、フィルタで1を返します.そうしないと0を返します.コードから分かるように、実はLogRecordです.nameのフィルタリング.
Filtererクラスには、Filterの抽象的なセットであるFilterオブジェクトのリストがあります.
重要なコードは次のとおりです.
4.loggingの上級クラス
以上の3つの基礎のクラスがあれば、より重要な高級クラスを組み合わせることができ、高級クラスはloggingの重要な機能を実現することができます.
4.1 Handler——logの出力過程を抽象化 HandlerクラスはFiltererから継承されます.Handlerクラスはlog出力というプロセスの抽象である. 同時にHandlerクラスは1つのメンバー変数selfを持つ.level,第2節で論じたログレベルのメカニズムは,Handlerで実現される. Handlerには、logの出力を担当するemit(record)関数があり、Handlerのサブクラスで実装する必要があります.
重要なコードは次のとおりです.
次に2つの簡単なhandlerのサブクラスを見てみましょう.実はloggingソースコードにはhandlerがあります.pyは、より複雑なhandlerを多く定義しており、ログをメモリにキャッシュしたり、ログをrotationしたりすることができます.
4.1.1 StreamHandler
最も簡単なhandler実装は、logをストリームに書き込む、デフォルトのstreamはsysである.stderr
重要なコードは次のとおりです.
4.1.2 FileHandler
ファイルにlogを出力するhandlerは、StreamHandlerから継承されます.
重要なコードは次のとおりです.
4.2 Logger-独立したlogパイプ
loggerとは? loggerクラスはFilterer, から継承される. loggerオブジェクトにloggerがある.levelログレベル loggerオブジェクト制御複数handler:logger.handlers=[] loggerオブジェクト間に親子関係がある 簡単に言えば、loggerというクラスは、私たち以上のすべてのLogRecordクラス、Filterクラス、Formatterクラス、handlerクラスを集めています.まず、loggerは入力に基づいてLogRecordオブジェクトを生成し、FilterとFormatterを通過する後、selfを通過する.handlersリストのすべてのhandlerは、logを送信します.1つのloggerには複数のhandlerがあり、1つのlogを複数の任意の位置に配置することができる.
重要なコード:
4.3 Manager——loggerのクラスを管理する
マネージャというクラスは,ユーザには実際には見えないが,ロガーが生成されると自動的に存在し,マネージャオブジェクトはすべてのロガーを管理する.
loggerとmanagerの関係について、いくつかまとめました. Loggerはログを出力するオブジェクトであり、Managerクラスは複数のLoggerを管理する機能を提供する. の1つのプログラムに1つのmanagerオブジェクトしか存在しない、managerを生成すると必ずRootLogger、managerオブジェクトのselfも生成する.rootはRootLogger を指しています managerオブジェクトのself.loggerDict、この辞書は現在のすべてのloggerオブジェクト(rootloggerを含まない) を保存しています. loggingを使用する場合.getLoggerのnameが空の場合、デフォルトではnameが「root」のRootLogger を指します. loggingを使用する場合.getLoggerのnameは空ではありません.生成されたloggerは、他の親logger を指定しない限り、RootLoggerの下に自動的にマウントされます.他のloggerはnameによって親子関係を確立する 親子関係の例:
これらの関係はmanagerで管理されています
重要なコード:
4.4 Logger Adapter-標準loggerへの拡張
LogRecordという大きな辞書で提供されているメンバー変数はすでにたくさんありますが、logを出力するときに自分が見たいもっと多くの情報を挟むことを望んでいる場合、例えばこのlogを生成するときに、いくつかの関数を呼び出して他の情報を得ると、これらをLoggerに追加することができ、Logger Adapterというクラスがこの役割を果たします.
LoggerAdapterというクラスは面白いですが、何かを変更しなければLoggerAdapterクラスとLoggerには違いはありません.Logger AdapterはLogger類をパッケージしただけです.
LoggerAdapterの使い方は、メンバー関数process()のコメントで説明されています.
すなわちprocess関数を書き換えると、次の例があります.
5.loggingのconfig関数
5.1 def basicConfig(**kwargs)
basicConfig関数では、各種パラメータが構成されます.パラメータが入力されない場合は、デフォルトの構成が行われます. format構成 handler構成 level構成
参照するloggingバージョンはpython 2です.7.3、私はloggingソースコードに中国語の注釈を加えて私のgithubに置いた.https://github.com/Stan-He/python_learn/tree/master/learn_logging
1.開始
最初は、loggingの基本機能を最短のコードで体験してみましょう
import logging
loger=logging.getLoger()
logging.basicConfig()
loger.setLevel('DEBUG')
loger.debug('logsomething')
#
out>>DEBUG:root:logsomething
2.loggingのログ・レベル
loggingはログを生成する際に、ログ・レベルのメカニズムがあり、デフォルトでは以下のログ・レベルがあります.
CRITICAL = 50
ERROR = 40
WARNING = 30
INFO = 20
DEBUG = 10
NOTSET = 0
各loggerオブジェクトには、levelより高いログのみを出力するログ・レベルがあります.loggerのレベルがINFOの場合、loggerが呼び出されます.debug()はログを出力できませんが、logger.warning()は出力できます.
一般的に、以上の6つのログ・レベルは、私たちの日常的な使用を完全に満たしています.
3.loggingのベースクラス
loggingはpythonのベースモジュールであり、pythonのソースコードの位置は以下の通りです.
#
/usr/lib/python2.7/logging/__init__.py
# handler config
/usr/lib/python2.7/logging/config.py
/usr/lib/python2.7/logging/handlers.py
ロゴを構成する主幹のいくつかの基礎クラスはすべて__にありますinit__.py:
3.1最初の基礎クラスLogRecord
ログ内の1行のデータに対応するLogRecordオブジェクト.通常は、時間、ログ・レベル、メッセージ情報、現在実行されているモジュール、行番号、関数名などが含まれます.これらの情報は、LogRecordオブジェクトに含まれます.LogRecordオブジェクトは大きな辞書として想像できます
class LogRecord(object):
#
def getMessage(self):
# self.msg
def makeLogRecord(dict):
# , LogRecord, , LogRecord
rv = LogRecord(None, None, "", 0, "", (), None, None)
rv.__dict__.update(dict)
return rv
3.2 2番目の基礎クラスFormatter
Formatterオブジェクトはログフォーマットを定義するために使用され、LogRecordは多くの情報を保存していますが、ログを打つときにいくつかしか必要ありません.Formatterはpythonの機能に依存する機能を提供しています.
# ,
print '%(name)s:%(num)d' % {'name':'my_name','num': 100}
out>>my_name:100
LogRecordが後の辞書なら、Formatterは前のフォーマット文字列・・・の抽象です
重要なコードは次のとおりです.
class Formatter(object):
def __init__(self,fmt=None,datefmt=None):
if fmt:
self._fmt = fmt
else:
# format
self._fmt = "%(message)s"
def format(self,record)
# self._fmt
s=self._fmt % record.__dict__
return s
3.3 3番目のベースクラスFilterとFilterer
Filterクラス、機能は簡単です.Flter.フィルタ()関数はLogRecordオブジェクトを入力し、フィルタで1を返します.そうしないと0を返します.コードから分かるように、実はLogRecordです.nameのフィルタリング.
Filtererクラスには、Filterの抽象的なセットであるFilterオブジェクトのリストがあります.
重要なコードは次のとおりです.
class Filter(object):
def __init__(self,name=''):
self.name=name
self.nlen=len(name)
def filter(self,record)
# 1 record ,0 record
if self.nlen==0:
return 1
elif self.name==record.name:
return 1
#record.name filter
elif record.name.find(self.name,0,self.nlen) !=0:
return 0
# .
return (record.name[self.nlen] == ".")
class Filterer(object):
# self.filters=[] filter
def addFilter(self,filter)
def removeFilter(self,filter)
def filter(self,record):
# filter , 0
# :
#filter1.name='A',filter2.name='A.B',filter3.name='A.B.C'
# record.name='A.B.C.D' record filter
4.loggingの上級クラス
以上の3つの基礎のクラスがあれば、より重要な高級クラスを組み合わせることができ、高級クラスはloggingの重要な機能を実現することができます.
4.1 Handler——logの出力過程を抽象化
重要なコードは次のとおりです.
class Handler(Filterer):
def __init__(self,level=NOTSET):
#handler level
self.level=_checkLevel(level)
def format(self,record):
# self.formatter,formatrecord
def handle(self,record):
# filter , emit log
rv=self.filter(record)
self.emit(record)
def emit(self,record):
#
次に2つの簡単なhandlerのサブクラスを見てみましょう.実はloggingソースコードにはhandlerがあります.pyは、より複雑なhandlerを多く定義しており、ログをメモリにキャッシュしたり、ログをrotationしたりすることができます.
4.1.1 StreamHandler
最も簡単なhandler実装は、logをストリームに書き込む、デフォルトのstreamはsysである.stderr
重要なコードは次のとおりです.
class StreamHandler(Handler):
def __init__(self, stream=None):
if stream is None:
stream=sys.stderr
self.stream=stream
def emit(self,record):
# record
#
fs='%s
' #
stream=self.stream
stream.write(fs % msg)
4.1.2 FileHandler
ファイルにlogを出力するhandlerは、StreamHandlerから継承されます.
重要なコードは次のとおりです.
class FileHandler(StreamHandler):
def __init__(self,filename, mode='a'):
#append ,
StreamHandler.__init__(self, self._open())
def emit(self,record):
# streamhandler
StreamHandler.emit(self, record)
4.2 Logger-独立したlogパイプ
loggerとは?
重要なコード:
class Logger(Filterer):
def __init__ (self,name,level=NONSET):
#handler
self.handlers=[]
self.level=_checkLevel(level)
def addHandler(self,hdlr):
def removeHandler(self,hdlr):
def _log(self, level, msg, args, exc_info=None, extra=None):
# _log LogRecord
record = self.makeRecord(self.name, level, fn, lno, msg, args, exc_info, func, extra)
# handle
self.handle(record)
def handle(self,record):
# filter, callHandlers
if (not self.disabled) and self.filter(record):
self.callHandlers(record)
def callHandlers(self, record):
# logger logger, handl record
c=self
while c:
for hdlr in c.handlers:
hdlr.handle(record) # handler emit log
……
c=c.parent
4.3 Manager——loggerのクラスを管理する
マネージャというクラスは,ユーザには実際には見えないが,ロガーが生成されると自動的に存在し,マネージャオブジェクトはすべてのロガーを管理する.
loggerとmanagerの関係について、いくつかまとめました.
loger1=logging.getLogger('A')
loger2=logging.getLogger('A.B')
#loger2 loger loger1
loger2.parent
out>>
#loger1 loger rootlogger
loger1.parent
out>>
これらの関係はmanagerで管理されています
重要なコード:
class Manager(object):
def getLogger(self,name):
# logger, logger manager self
# logger
def _fixupParents(self,aloger):
def _fixupChildren(self,ph,aloger):
# logger
4.4 Logger Adapter-標準loggerへの拡張
LogRecordという大きな辞書で提供されているメンバー変数はすでにたくさんありますが、logを出力するときに自分が見たいもっと多くの情報を挟むことを望んでいる場合、例えばこのlogを生成するときに、いくつかの関数を呼び出して他の情報を得ると、これらをLoggerに追加することができ、Logger Adapterというクラスがこの役割を果たします.
LoggerAdapterというクラスは面白いですが、何かを変更しなければLoggerAdapterクラスとLoggerには違いはありません.Logger AdapterはLogger類をパッケージしただけです.
LoggerAdapterの使い方は、メンバー関数process()のコメントで説明されています.
def process(self, msg, kwargs):
"""
Normally, you'll only need to override this one method in a
LoggerAdapter subclass for your specific needs.
"""
すなわちprocess関数を書き換えると、次の例があります.
import logging
import random
L=logging.getLogger('name')
# , 0~1000
def func():
return random.randint(1,1000)
class myLogger(logging.LoggerAdapter):
# LoggerAdapter, process, msg
def process(self,msg,kwargs):
return '(%d),%s' % (self.extra['name'](),msg) ,kwargs
#
LA=myLogger(L,{'name':func})
#now,do some logging
LA.debug('some_loging_messsage')
out>>DEBUG:name:(167),some_loging_messsage
5.loggingのconfig関数
5.1 def basicConfig(**kwargs)
basicConfig関数では、各種パラメータが構成されます.パラメータが入力されない場合は、デフォルトの構成が行われます.