程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python 日志記錄-loguru

編輯:Python

Python 日志記錄-loguru

引言

loguru是一個第三方庫,用來記錄日志的。使用起來比較方便,且功能比較全面。

官方文檔

  • GitHub - Delgan/loguru: Python logging made (stupidly) simple

  • loguru.logger — loguru documentation

安裝

pip install loguru

日志級別

Level nameSeverity valueLogger methodTRACE5logger.traceDEBUG10logger.debugINFO20logger.infoSUCCESS25logger.successWARNING30logger.warningERROR40logger.errorCRITICAL50logger.critical

簡單測試下

from loguru import logger
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

輸出結果

特性

簡介

此函數應用於注冊接收器,這些接收器負責管理使用記錄字典上下文化的日志消息。接收器可以采用多種形式:簡單函數、字符串路徑、類似文件的對象、協程函數或內置處理程序。

請注意:可以使用remove()函數來刪除以前添加的處理程序。

例子:

import sys
from loguru import logger
logger.add("test.log", format="{time} {level} {message}", filter="", level="INFO", encoding="utf-8")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

效果,輸出日志到test.log文件

2022-07-27T17:14:36.393072+0800 INFO info
2022-07-27T17:14:36.394068+0800 SUCCESS success
2022-07-27T17:14:36.395066+0800 WARNING warning
2022-07-27T17:14:36.396063+0800 ERROR error
2022-07-27T17:14:36.397060+0800 CRITICAL critical

rotation/retension/compression

官方介紹:loguru.logger — loguru documentation

rotation:指示何時應關閉當前記錄的文件並創建新文件,可以是文件大小/每天的時間點/時間間隔等。

logger.add("test1.log", rotation="500 MB") # 日志文件超過500M創建新的文件
logger.add("test2.log", rotation="12:00") # 每天中午12點創建新的日志文件
logger.add("test3.log", rotation="1 week") # 當前使用的日志文件超過1周,創建新的日志文件

retension:指示合適應該刪除舊文件。

logger.add("test4.log", retention="10 days") # 超過十天的日志文件刪除

compression:日志文件在關閉時應轉換為的壓縮或歸檔格式。

logger.add("test5.log", compression="zip") # 日志文件關閉後,使用zip進行壓縮

異常捕獲

使用catch()裝飾器或者上下文管理器可以捕獲異常,確保任何錯誤都能夠記錄到log日志中。

裝飾器

from loguru import logger
@logger.catch
def test(x, y, z):
return 1 / (x + y + z)
test(0, 1, -1)

上下文裝飾器

from loguru import logger
def test(x, y, z):
return 1 / (x + y + z)
with logger.catch():
test(0, 1, -1)

輸出結果

完全描述性異常

記錄代碼中發生的異常對於跟蹤BUG非常重要,loguru允許顯示整個堆棧跟蹤(包括變量值)來幫助定位BUG原因。

logger.add("out.log", backtrace=True, diagnose=True) # Caution, may leak sensitive data in prod
def func(a, b):
return a / b
def nested(c):
try:
func(5, c)
except ZeroDivisionError:
logger.exception("What?!")
nested(0)

輸出結果

自定義顏色

logger.add(sys.stdout, colorize=True, format="<red>{time}</red> <level>{message}</level>")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

輸出結果

異步/線程安全/多進程安全

默認情況下,添加到log的所有接收器都是線程安全的,但他們不是多進程安全的。如果需要實現多進程安全,異步記錄日志,需要添加一個enqueue參數:

logger.add("test.log", enqueue = True)

結構化日志記錄

將消息轉化為json字符串以便於傳遞或者解析,可以使用serialize來配置:

logger.add("test.log", serialize=True, encoding="utf-8")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

輸出結果

{"text": "2022-07-28 11:25:44.434 | DEBUG | __main__:<module>:43 - debug\n", "record": {"elapsed": {"repr": "0:00:00.127658", "seconds": 0.127658}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "", "name": "DEBUG", "no": 10}, "line": 43, "message": "debug", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.434074+08:00", "timestamp": 1658978744.434074}}}
{"text": "2022-07-28 11:25:44.436 | INFO | __main__:<module>:44 - info\n", "record": {"elapsed": {"repr": "0:00:00.129653", "seconds": 0.129653}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "️", "name": "INFO", "no": 20}, "line": 44, "message": "info", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.436069+08:00", "timestamp": 1658978744.436069}}}
{"text": "2022-07-28 11:25:44.438 | SUCCESS | __main__:<module>:45 - success\n", "record": {"elapsed": {"repr": "0:00:00.131648", "seconds": 0.131648}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "️", "name": "SUCCESS", "no": 25}, "line": 45, "message": "success", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.438064+08:00", "timestamp": 1658978744.438064}}}
{"text": "2022-07-28 11:25:44.439 | WARNING | __main__:<module>:46 - warning\n", "record": {"elapsed": {"repr": "0:00:00.132645", "seconds": 0.132645}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "️", "name": "WARNING", "no": 30}, "line": 46, "message": "warning", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.439061+08:00", "timestamp": 1658978744.439061}}}
{"text": "2022-07-28 11:25:44.440 | ERROR | __main__:<module>:47 - error\n", "record": {"elapsed": {"repr": "0:00:00.133642", "seconds": 0.133642}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "", "name": "ERROR", "no": 40}, "line": 47, "message": "error", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.440058+08:00", "timestamp": 1658978744.440058}}}
{"text": "2022-07-28 11:25:44.442 | CRITICAL | __main__:<module>:48 - critical\n", "record": {"elapsed": {"repr": "0:00:00.135637", "seconds": 0.135637}, "exception": null, "extra": {}, "file": {"name": "logutil.py", "path": "e:\\GitPorject\\ZanguS1\\ZanguRecorder\\common\\logutil.py"}, "function": "<module>", "level": {"icon": "️", "name": "CRITICAL", "no": 50}, "line": 48, "message": "critical", "module": "logutil", "name": "__main__", "process": {"id": 15768, "name": "MainProcess"}, "thread": {"id": 10228, "name": "MainThread"}, "time": {"repr": "2022-07-28 11:25:44.442053+08:00", "timestamp": 1658978744.442053}}}

使用bind()添加額外的屬性:

logger.add("test.log", format="{extra[ip]} {extra[user]} {message}")
context_logger = logger.bind(ip="192.168.0.1", user="someone")
context_logger.info("Contextualize your logger easily")
context_logger.bind(user="someone_else").info("Inline binding of extra attribute")
context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody")

輸出結果

192.168.0.1 someone Contextualize your logger easily
192.168.0.1 someone_else Inline binding of extra attribute
192.168.0.1 anybody Use kwargs to add context during formatting: anybody

使用bind()和filter對日志進行過濾:

logger.add("test.log", filter=lambda record: "special" in record["extra"])
logger.debug("This message is not logged to the file")
logger.bind(special=True).info("This message, though, is logged to the file!")

輸出結果

2022-07-28 11:33:58.214 | INFO | __main__:<module>:58 - This message, though, is logged to the file!

自定義級別

Loguru 附帶了所有標准日志記錄級別,額外添加了trace和success。如果需要自定義級別,可以使用level()函數來創建:

new_level = logger.level("test2", no=66, color="<black>", icon="")
logger.log("test2", "Here we go!")

輸出結果:

日期時間處理

logger.add("test.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")
logger.debug("debug")
logger.info("info")
logger.success("success")
logger.warning("warning")
logger.error("error")
logger.critical("critical")

輸出結果:

2022-07-28 at 11:41:32 | DEBUG | debug
2022-07-28 at 11:41:32 | INFO | info
2022-07-28 at 11:41:32 | SUCCESS | success
2022-07-28 at 11:41:32 | WARNING | warning
2022-07-28 at 11:41:32 | ERROR | error
2022-07-28 at 11:41:32 | CRITICAL | critical

loguru配置

在腳本中使用記錄器很容易,您可以在開始時configure()它。要從庫中使用 Loguru,請記住永遠不要調用 add(),而是使用 disable(),以便日志記錄函數變為 no-op。如果開發人員希望查看庫的日志,他可以再次enable() 它。

# For scripts
config = {

"handlers": [
{
"sink": sys.stdout, "format": "{time} - {message}"},
{
"sink": "test.log", "serialize": True},
],
"extra": {
"user": "someone"}
}
logger.configure(**config)
# For libraries
logger.disable("my_library")
logger.info("No matter added sinks, this message is not displayed")
logger.enable("my_library")
logger.info("This message however is propagated to the sinks")

通知程序

Loguru 可以和強大的郵件通知模塊 notifiers 庫結合使用,以在程序意外失敗時接收電子郵件,或發送許多其他類型的通知。

import notifiers
params = {

"username": "[email protected]",
"password": "abc123",
"to": "[email protected]"
}
# Send a single notification
notifier = notifiers.get_notifier("gmail")
notifier.notify(message="The application is running!", **params)
# Be alerted on each error message
from notifiers.logging import NotificationHandler
handler = NotificationHandler("gmail", defaults=params)
logger.add(handler, level="ERROR")

尾語

希望能幫助到大家,如果又說的不對的地方,歡迎大家指正。

]


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved