Heim >Backend-Entwicklung >Python-Tutorial >So verwenden Sie die integrierte Protokollierung von Python
Bietet Protokollierungsschnittstellen und zahlreiche Verarbeitungsmodule, mit denen Benutzer Protokolle in verschiedenen Formaten speichern, beim Debuggen von Programmen helfen oder Ausgabeinformationen während der Programmausführung aufzeichnen können.
Protokollierungsebene ist in fünf Ebenen unterteilt, die Priorität von hoch nach niedrig ist:
**KRITISCH; **Schwerwiegender Programmfehler
**FEHLER; **Programmfehler/Teilfunktionsfehler
**WARNUNG; **Programmfehler können auftreten
**INFO; **Informationen, wenn das Programm normal ausgeführt wird
DEBUG-Programm-Debugging-Informationen
Die Standardprotokollaufzeichnungsstufe ist WARNUNG, d wird nur aufgezeichnet, wenn er größer oder gleich WARNING ist.
Der häufig verwendete Aufzeichnungspegel ist INFO, der zum Aufzeichnen einiger Informationen über den normalen Betrieb des Programms verwendet wird (ähnlich wie beim Drucken).
Wenn die Protokollebene WARNUNG oder höher erreicht, bedeutet dies, dass das Programm zu diesem Zeitpunkt nicht normal ausgeführt werden kann.
logging.basicConfig(**kwargs)
erstellt standardmäßig einen Root-Logger, wenn kein expliziter Logger erstellt wird. logging.basicConfig(**kwargs) kann ein streamHandle mit einem Standardformatierer erstellen und es dem Root-Logger hinzufügen, um die Grundkonfiguration zu initialisieren.
Zum Beispiel
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')
Im obigen Code erstellt die Protokollierung nicht explizit einen Logger (logging.getLogger), sondern verwendet die Standardeinstellung, wenn debug(), info(), warning(), error(), Critical( verwendet wird). ) direkt. Der Root-Logger ruft automatisch die benutzerdefinierte oder standardmäßige Datei logging.basicConfig(**kwargs) auf, um den Root-Logger zu initialisieren.
Die Parameter in der benutzerdefinierten logging.basicConfig(**kwargs) haben die folgenden Hauptoptionen:
Parameter | Funktion |
---|---|
Dateiname | Geben Sie den Dateinamen zum Speichern des Protokolls an und verwenden Sie die angegebene Datei Name Erstellen Sie einen FileHandler. Das aufgezeichnete Protokoll wird in der Datei gespeichert / Zeitformat, dasselbe wie das von time.strftime() akzeptierte. |
level | Geben Sie die Root-Logger-Ebene an, die Standardeinstellung ist logging.WARNUNG |
stream | Geben Sie den Ausgabestream des Protokolls an. Sie können die Ausgabe in sys.stderr, std.stdout oder in einer Datei angeben. Die Standardausgabe ist sys .stderr. Initialisieren Sie StramHandler mit dem angegebenen Stream. Hinweis: Wenn beide gleichzeitig verwendet werden, wird ein ValueError ausgelöst. Beispielsweise wird der Root-Logger durch Anpassen von logging.basicConfig(**kwargs) initialisiert. Rufen Sie unten Protokolldatensätze auf der DEBUG-Ebene ab und speichern Sie sie in der Datei log.txt. |
Logger | Neben dem Root-Logger (Root-Logger) ist das Wichtigste, dass Sie Ihren eigenen Logger erstellen können. |
Standardmäßig nimmt der Logger eine hierarchische Struktur an und verschiedene Ebenen werden durch . unterschieden . Wenn es beispielsweise einen Logger mit dem Namen foo gibt, dann sind foo.a und foo.b beide untergeordnete Elemente von foo Code> Pegelschreiber. Natürlich ist der Logger der ersten oder obersten Ebene der Root-Logger. Wenn name=None, wird der Root-Logger erstellt.
|
Sie können den Namen des aktuellen Moduls direkt als Namen des Loggers verwenden logging.getLogger(__name__)
|
logging.getLogger(name)
实例化记录器
默认情况下,记录器采用层级结构,通过 .
来区分不同的层级。比如 有个名叫 foo
的记录器 则 foo.a
和 foo.b
都是 foo
的子级记录器。当然,最开始的或者说最上层的记录器就是 root logger。如果 name=None,构建的是root logger。
可以直接用当前模块的名称当作记录器的名字 logging.getLogger(__name__)
子级记录器通常不需要单独设置日志级别以及 Handler,如果子级记录器没有单独设置,则它的行为会委托给父级。比如说,记录器foo
的级别为INFO,而foo.a
和 foo.b
都不设置日志级别。此时foo.a
和 foo.b
会遵循foo
Logger.addFilter()
Ein Filterobjekt hinzufügen
Entfernen Sie ein Filterobjekt. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Logger.info() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Logger.error() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Logger.critical() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Logger.Exception( ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Logger.log() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Handler.setLevel() | Legen Sie den minimalen Schweregrad der Protokollnachrichten fest, die der Prozessor verarbeiten soll | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Handler.setFormatter() | Legen Sie ein Formatobjekt für den Prozessor fest | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Handler.addFilter () | Fügen Sie ein Filterobjekt für den Handler hinzu. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Handler.removeFilter() | Entfernen Sie ein Filterobjekt für den Handler Ausgabestream, wie std.out, std.err | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logging.FilterHandler() | Senden Sie Protokollnachrichten an Festplattendateien. Standardmäßig wächst die Dateigröße unendlich | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RotationFileHandler() | Protokoll senden Nachrichten an Festplattendateien, unterstützt das Schneiden von Protokolldateien nach Größe | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TimeRotatingFileHandler() | sendet Protokollnachrichten an Festplattendateien und unterstützt das Schneiden von Protokolldateien nach Zeit | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logging.handers.HTTPHandler() | sendet Protokollnachrichten per GET oder POST an einen HTTP-Server | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
logging.handlers.SMTPHandler() | Protokollnachrichten an E-Mail-Adresse senden | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 具有以下优点:
|
Das obige ist der detaillierte Inhalt vonSo verwenden Sie die integrierte Protokollierung von Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!