ユーザーがプログラムのデバッグやプログラム実行中の出力情報の記録に役立つように、ログをさまざまな形式で保存するためのロギング インターフェイスと多数の処理モジュールを提供します。
logging ログ レベルは 5 つのレベルに分かれており、優先順位は高から低の順です:
**CRITICAL; ** 重大なプログラム エラー
**ERROR; **プログラムエラー/部分関数エラー
**WARNING; **プログラムにエラーがある可能性があります
**INFO; **プログラムが正常に実行中 情報
DEBUG プログラムのデバッグ情報
デフォルトのログ記録レベルは WARNING です。つまり、ログ レベルが WARNING 以上の場合にのみ記録されます。
一般的に使用される記録レベルは INFO で、プログラムの通常の動作に関する情報を記録するために使用されます (印刷と同様)。
ログ レベルが WARNING 以上に達すると、現時点ではプログラムが正常に実行できないことを示します。
logging.basicConfig(**kwargs)
は、明示的にRecorder ( logger) を使用すると、ルート ロガーがデフォルトで作成されます。logging.basicConfig(**kwargs) は、デフォルトの Formatter を使用して streamHandle を作成し、それをルート ロガーに追加して基本構成を初期化できます。
例
import logging logging.debug('Debug code!') logging.info('Run code!') logging.warning('Watch out!') logging.error('This is an error') logging.critical('This is a ciritical')
上記のコードでは、ロギングは明示的にロガー (logging.getLogger) を作成せず、debug()、info()、warning()、error() を直接使用します。 ) の場合、critical() が呼び出されたときにデフォルトのルート ロガーが使用され、ルート ロガーを初期化するためにカスタムまたはデフォルトのlogging.basicConfig(**kwargs) が自動的に呼び出されます。
カスタムlogging.basicConfig(**kwargs)のパラメータには、次の主なオプションがあります:
パラメータ | 関数 |
---|---|
filename | ログを保存するファイル名を指定し、指定したファイル名で FileHandler を作成すると、記録されたログがファイルに保存されます |
format | 出力の形式と内容を指定します。デフォルトは、コロンで区切られたレベル名、名前、メッセージです。 |
datefmt | Use 指定された日付/時刻形式。time.strftime() で受け入れられる形式と同じです。 |
level | ルート ロガー レベルを指定します。デフォルトはロギングです。警告 |
stream | ログの出力ストリームを指定します。出力を sys.stderr、std.stdout、またはファイルに指定できます。デフォルトの出力は sys.stderr です。指定されたストリームを使用して StramHandler を初期化します。 注: ストリーム パラメータとファイル名パラメータには互換性がありません。両方を同時に使用すると、ValueError が発生します。 |
例:次のカスタムlogging.basicConfig (**kwargs)を使用してルートロガーを初期化し、DEBUGレベル以上のログレコードを取得し、log.txtファイルに保存します。
import logging logging.basicConfig(filename='./log.txt', format='%(asctime)s-%(name)s-%(levelname)s-%(message)s-%(funcName)s:%(lineno)d', level=logging.DEBUG) logging.debug('Debug code!') logging.info('Run code!') logging.warning('Watch out!') logging.error('This is an error') logging.critical('This is a ciritical')
Logger
ルート ロガー (ルート ロガー) に加えて、最も重要なことは、独自のロガー。
モジュールレベルの関数を通じてlogging.getLogger(name)
ロガーをインスタンス化する
デフォルトでは、ロガーは .
による階層構造を採用します。さまざまなレベルを区別するため。たとえば、foo
という名前のロガーがある場合、foo.a
と foo.b
は両方とも foo
の子ロガーです。もちろん、最初または最上位のロガーはルート ロガーです。 name=None の場合、ルート ロガーが構築されます。
現在のモジュールの名前をロガーの名前として直接使用できますlogging.getLogger(__name__)
子レベルのロガーは通常、設定する必要はありませんログ レベルとハンドラーを個別に設定する場合、子ロガーが個別に設定されていない場合、その動作は親に委任されます。たとえば、ロガー foo
のレベルは INFO ですが、foo.a
と foo.b
のどちらにもログ レベルが設定されていません。現時点では、foo.a
と foo.b
は foo
のレベル設定に従います。つまり、INFO 以上のレベルを持つログのみが出力されます。 foo が設定されていない場合は、ルート ロガーが見つかります。ルートのデフォルト レベルは WARGING です。
ロガー クラスの一般的に使用されるいくつかのメソッド
メソッド | 関数の説明 |
---|---|
Logger.setLevel() | ロガーが処理するログ メッセージ レベルを設定します |
Logger.addHandler() | ハンドラー オブジェクトの追加 |
Logger.removeHandler() | ハンドラー オブジェクトの削除 |
Logger.addFilter( ) | フィルター オブジェクトの追加 |
Logger.removeFilter() | フィルター オブジェクトの削除 |
Logger.debug () | DEBUG レベルのログを設定します |
Logger.info() | INFO レベルのログを設定します |
Logger.warning() | 警告レベルのログの設定 |
Logger.error() | エラー レベルのログの設定 |
Logger.critical() | CRITICAL レベルのログ記録を設定します |
Logger.Exception( ) | スタック トレース情報を出力します |
Logger.log() | カスタム レベル パラメータを設定してログ レコードを作成する |
logger は、後で紹介する他の 3 つのコンポーネントと組み合わせて、次の機能を実現できます。
Logger は、ハンドラーを介してターゲットの場所にログ情報を出力する必要があります。場所は sys.stdout や files などになります (これはlogging.basicConfig(**kwargs)設定と一致しません)。
ロガーは異なるハンドラーを設定でき、異なるハンドラーは異なる場所 (異なるログ ファイル) にログを出力でき、各ハンドラーは独自のフィルターを設定してログ フィルタリングを実装し、ログを保持できます。実際のプロジェクトでは必要になります。同時に、各 Handler は異なる Formatter を設定することもでき、各 Formatter は同じログを異なる形式で異なる場所に出力できることを実現します。
ハンドル
プロセッサ; 記録されたログの出力先 (標準出力/ファイル/...) を制御でき、プロセッサはフィルター Filter および Filter を追加することもできます。フォーマッタは、出力コンテンツと出力形式を制御するために使用されます。
これには、いくつかの共通プロセッサがあります:
logging.StreamHandler 標準ストリーム プロセッサ。メッセージを標準出力ストリームとエラー ストリームに送信します-->logging .StreamHandler( sys.stdout) # sys.stdout は、コンソール、つまり標準出力を指すことを意味します。Python でオブジェクトを印刷するために print obj を呼び出すとき、実際には sys.stdout.write(obj '\n') を呼び出します。
print は、必要なコンテンツをコンソールに出力し、改行文字を追加します。
logging.FileHandler ファイル ハンドラー、メッセージ送信先file -->logging.FileHandler(log_path)
logging.RotatingFileHandler ファイル ハンドラー、ファイルが指定されたサイズに達した後、新しいファイルでログを保存できるようにします
logging.TimedRotatingFileHandler ファイル ハンドラー、ログは特定の時間間隔でログ ファイルをローテーションします
ハンドル クラスのいくつかの一般的なメソッド
プロセッサが処理するログ メッセージの最小重大度レベルを設定します | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
プロセッサのフォーマット オブジェクトを設定します | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
プロセッサのフィルタ オブジェクトを追加します | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ハンドラーのフィルター オブジェクトを削除します。 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ログ メッセージを出力ストリーム (std.out、std.err など) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ログ メッセージをディスク ファイルに送信します。デフォルトでは、ファイル サイズは大きくなります。ワイヤレス | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ログ メッセージをディスク ファイルに送信し、サイズに応じたログ ファイルの切り取りをサポートします | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ログ メッセージをディスク ファイルに送信し、時間によるログ ファイルの分割をサポートします | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GET 経由でログ メッセージを送信しますまたは HTTP サーバーに POST | #logging.handlers.SMTPHandler() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
## Filter filter组件用来过滤 logger 对象,一个 filter 可以直接添加到 logger对象上,也可以添加到 handler 对象上,而如果在logger和handler中都设置了filter,则日志是先通过logger的filter,再通过handler的filter。由于所有的信息都可以经过filter,所以filter不仅可以过滤信息,还可以增加信息。 Filter 类的实例化对象可以通过 logging.Filter(name) 来创建,其中name 为 记录器的名字,如果没有创建过该名字的记录器,就不会输出任何日志: filter = logging.Filter("foo.a") 基本过滤器类只允许低于指定的日志记录器层级结构中低于特定层级的事件,例如 这个用 Filter 类 有 三个方法 :
Formatter 格式化日志的输出;实例化: 其中 fmt 参数 有以下选项:
例如: formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s') # -表示右对齐 8表示取8位 handler.formatter = formatter datefmt 参数 有以下选项:
例如: formatter = logging.Formatter('%(asctime)s %(levelname)-8s: %(message)s') # -表示右对齐 8表示取8位 handler.formatter = formatter datefmt 参数 有以下选项:
例子: formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s","%Y%m%d-%H:%M:%S") handler.formatter = formatter logging 的配置
在 loguser.conf 中 写入相关的信息 [loggers] keys=root,fileLogger,rotatingFileLogger [handlers] keys=consoleHandler,fileHandler,rotatingFileHandler [formatters] keys=simpleFormatter [logger_root] level=INFO handlers=consoleHandler [logger_fileLogger] level=INFO handlers=fileHandler qualname=fileLogger propagate=0 [logger_rotatingFileLogger] level=INFO handlers=consoleHandler,rotatingFileHandler qualname=rotatingFileLogger propagate=0 [handler_consoleHandler] class=StreamHandler level=INFO formatter=simpleFormatter args=(sys.stdout,) [handler_fileHandler] class=FileHandler level=INFO formatter=simpleFormatter args=("logs/fileHandler_test.log", "a") [handler_rotatingFileHandler] class=handlers.RotatingFileHandler level=WARNING formatter=simpleFormatter args=("logs/rotatingFileHandler.log", "a", 10*1024*1024, 50) [formatter_simpleFormatter] format=%(asctime)s - %(module)s - %(levelname)s -%(thread)d : %(message)s datefmt=%Y-%m-%d %H:%M:%S
from logging import config with open('./loguser.conf', 'r', encoding='utf-8') as f: ## 加载配置 config.fileConfig(f) ## 创建同名Logger,其按照配置文件的handle,formatter,filter方法初始化 logger = logging.getLogger(name="fileLogger")
在 loguser.yaml文件 中 配置相关信息 version: 1 disable_existing_loggers: False # formatters配置了日志输出时的样式 # formatters定义了一组formatID,有不同的格式; formatters: brief: format: "%(asctime)s - %(message)s" simple: format: "%(asctime)s - [%(name)s] - [%(levelname)s] :%(levelno)s: %(message)s" datefmt: '%F %T' # handlers配置了需要处理的日志信息,logging模块的handler只有streamhandler和filehandler handlers: console: class : logging.StreamHandler formatter: brief level : DEBUG stream : ext://sys.stdout info_file_handler: class : logging.FileHandler formatter: simple level: ERROR filename: ./logs/debug_test.log error_file_handler: class: logging.handlers.RotatingFileHandler level: ERROR formatter: simple filename: ./logs/errors.log maxBytes: 10485760 # 10MB #1024*1024*10 backupCount: 50 encoding: utf8 loggers: #fileLogger, 就是在代码中通过logger = logging.getLogger("fileLogger")来获得该类型的logger my_testyaml: level: DEBUG handlers: [console, info_file_handler,error_file_handler] # root为默认情况下的输出配置, 当logging.getLogger("fileLoggername")里面的fileLoggername没有传值的时候, # 就是用的这个默认的root,如logging.getLogger(__name__)或logging.getLogger() root: level: DEBUG handlers: [console] 同样的可以通过导入 yaml 文件加载配置 with open('./loguser.yaml', 'r', encoding='utf-8') as f: yaml_config = yaml.load(stream=f, Loader=yaml.FullLoader) config.dictConfig(config=yaml_config) root = logging.getLogger() # 子记录器的名字与配置文件中loggers字段内的保持一致 # loggers: # my_testyaml: # level: DEBUG # handlers: [console, info_file_handler,error_file_handler] my_testyaml = logging.getLogger("my_testyaml") logging 和 print 的区别看起来logging要比print复杂多了,那么为什么推荐在项目中使用 logging 记录日志而不是使用print 输出程序信息呢。 相比与print logging 具有以下优点:
|
以上がPython の組み込みロギングの使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。