在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Python更優(yōu)雅的日志記錄解決方案Loguru

馬哥Linux運(yùn)維 ? 來源:Escape ? 作者:Escape ? 2021-11-18 11:24 ? 次閱讀

Loguru: 更優(yōu)雅的日志記錄解決方案!

loguru是一個(gè)Python簡易且強(qiáng)大的第三方日志記錄庫,該庫旨在通過添加一系列有用的功能來解決標(biāo)準(zhǔn)記錄器的注意事項(xiàng),從而減少Python日志記錄的痛苦。

1. 引入原因

簡單且方便的幫助我們輸出需要的日志信息!

  • 使用Python來寫程序或者腳本的話,常常遇到的問題就是需要對日志進(jìn)行刪除。一方面可以幫助我們在程序出問題的時(shí)候排除問題,二來可以幫助我們記錄需要關(guān)注的信息。

  • 但是,使用自帶自帶的logging模塊的話,則需要我們進(jìn)行不同的初始化等相關(guān)工作。對應(yīng)不熟悉該模塊的同學(xué)來說,還是有些費(fèi)勁的,比如需要配置Handler/Formatter等。

import logging
logger = logging.getLogger('xxx')handler = logging.StreamHandler()formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s')handler.setFormatter(formatter)logger.addHandler(handler)logger.setLevel(logging.DEBUG)
logger.debug('This is a %s', 'test')
  • loguru就是一個(gè)可以開箱即用的日志記錄模塊,我們不再需要復(fù)雜的初始化操作就可以通過如下命令來記錄日志信息了。

# pip$ pip install loguru

2. 功能特性

有很多優(yōu)點(diǎn),以下列舉了其中比較重要的幾點(diǎn)!

  • 開箱即用,無需準(zhǔn)備

  • 無需初始化,導(dǎo)入函數(shù)即可使用

  • 更容易的文件日志記錄與轉(zhuǎn)存/保留/壓縮方式

  • 更優(yōu)雅的字符串格式化輸出

  • 可以在線程或主線程中捕獲異常

  • 可以設(shè)置不同級別的日志記錄樣式

  • 支持異步,且線程和多進(jìn)程安全

  • 支持惰性計(jì)算

  • 適用于腳本和庫

  • 完全兼容標(biāo)準(zhǔn)日志記錄

  • 更好的日期時(shí)間處理


3. 快速上手

介紹 loguru 的常用操作和功能介紹!

[1] 開箱即用,無需準(zhǔn)備

    • loguru并沒有什么黑科技,只是它預(yù)先幫助我們設(shè)置好了相關(guān)的配置,我們導(dǎo)入之后即可直接使用。

from loguru import logger
logger.debug("That's it, beautiful and simple logging!")

[2] 無需初始化,導(dǎo)入函數(shù)即可使用

  • 如何添加處理程序(handler)呢?

  • 如何設(shè)置日志格式(logs formatting)呢?

  • 如何過濾消息(filter messages)呢?

  • 如何如何設(shè)置級別(log level)呢?

# addlogger.add(sys.stderr,     format="{time} {level} {message}",    filter="my_module",    level="INFO")

[3] 更容易的文件日志記錄與轉(zhuǎn)存/保留/壓縮方式

# 日志文件記錄logger.add("file_{time}.log")
# 日志文件轉(zhuǎn)存logger.add("file_{time}.log", rotation="500 MB")logger.add("file_{time}.log", rotation="12:00")logger.add("file_{time}.log", rotation="1 week")
# 多次時(shí)間之后清理logger.add("file_X.log", retention="10 days")
# 使用zip文件格式保存logger.add("file_Y.log", compression="zip")

[4] 更優(yōu)雅的字符串格式化輸出

logger.info(    "If you're using Python {}, prefer {feature} of course!",    3.6, feature="f-strings")

[5] 在線程或主線程中捕獲異常

@logger.catchdef my_function(x, y, z):    # An error? It's caught anyway!    return 1 / (x + y + z)
my_function(0, 0, 0)

[6] 可以設(shè)置不同級別的日志記錄樣式

  • Loguru會自動為不同的日志級別,添加不同的顏色進(jìn)行區(qū)分,當(dāng)然我們也是可以自定義自己喜歡的顯示顏色樣式的。

logger.add(sys.stdout,    colorize=True,    format="{time} {message}")
logger.add('logs/z_{time}.log',           level='DEBUG',           format='{time:YYYY-MM-DD ss} - {level} - {file} - {line} - {message}',           rotation="10 MB")

[7] 支持異步且線程和多進(jìn)程安全

  • 默認(rèn)情況下,添加到logger中的日志信息都是線程安全的。但這并不是多進(jìn)程安全的,我們可以通過添加enqueue參數(shù)來確保日志完整性。

  • 如果我們想要在異步任務(wù)中使用日志記錄的話,也是可以使用同樣的參數(shù)來保證的。并且通過complete()來等待執(zhí)行完成。

# 異步寫入logger.add("some_file.log", enqueue=True)

[8] 異常的完整性描述

  • 用于記錄代碼中發(fā)生的異常的bug跟蹤,Loguru通過允許顯示整個(gè)堆棧跟蹤(包括變量值)來幫助您識別問題。

logger.add("out.log", backtrace=True, diagnose=True)
def func(a, b):    return a / b
def nested(c):    try:        func(5, c)    except ZeroDivisionError:        logger.exception("What?!")
nested(0)

[9] 結(jié)構(gòu)化日志記錄

  • 對日志進(jìn)行序列化以便更容易地解析或傳遞數(shù)據(jù)結(jié)構(gòu),使用序列化參數(shù),在將每個(gè)日志消息發(fā)送到配置的接收器之前,將其轉(zhuǎn)換為JSON字符串。

  • 同時(shí),使用bind()方法,可以通過修改額外的record屬性來將日志記錄器消息置于上下文中。還可以通過組合bind()filter對日志進(jìn)行更細(xì)粒度的控制。

  • 最后patch()方法允許將動態(tài)值附加到每個(gè)新消息的記錄dict上。

# 序列化為json格式logger.add(custom_sink_function, serialize=True)
# bind方法的用處logger.add("file.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")
# 粒度控制logger.add("special.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!")
# patch()方法的用處logger.add(sys.stderr, format="{extra[utc]} {message}")logger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow()))

[10] 惰性計(jì)算

  • 有時(shí)希望在生產(chǎn)環(huán)境中記錄詳細(xì)信息而不會影響性能,可以使用opt()方法來實(shí)現(xiàn)這一點(diǎn)。

logger.opt(lazy=True).debug("If sink level <= DEBUG: {x}", x=lambda: expensive_function(2**64))
# By the way, "opt()" serves many usageslogger.opt(exception=True).info("Error stacktrace added to the log message (tuple accepted too)")logger.opt(colors=True).info("Per message colors")logger.opt(record=True).info("Display values from the record (eg. {record[thread]})")logger.opt(raw=True).info("Bypass sink formatting
")logger.opt(depth=1).info("Use parent stack context (useful within wrapped functions)")logger.opt(capture=False).info("Keyword arguments not added to {dest} dict", dest="extra")

[11] 可定制的級別

new_level = logger.level("SNAKY", no=38, color="", icon="")logger.log("SNAKY", "Here we go!")

[12] 適用于腳本和庫

# For scriptsconfig = {    "handlers": [        {"sink": sys.stdout, "format": "{time} - {message}"},        {"sink": "file.log", "serialize": True},    ],    "extra": {"user": "someone"}}logger.configure(**config)
# For librarieslogger.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")

[13] 完全兼容標(biāo)準(zhǔn)日志記錄

  • 希望使用Loguru作為內(nèi)置的日志處理程序?

  • 需要將Loguru消息到標(biāo)準(zhǔn)日志?

  • 想要攔截標(biāo)準(zhǔn)的日志消息到Loguru中匯總?

handler = logging.handlers.SysLogHandler(address=('localhost', 514))logger.add(handler)

class PropagateHandler(logging.Handler):    def emit(self, record):        logging.getLogger(record.name).handle(record)
logger.add(PropagateHandler(), format="{message}")
class InterceptHandler(logging.Handler):    def emit(self, record):        # Get corresponding Loguru level if it exists        try:            level = logger.level(record.levelname).name        except ValueError:            level = record.levelno
        # Find caller from where originated the logged message        frame, depth = logging.currentframe(), 2        while frame.f_code.co_filename == logging.__file__:            frame = frame.f_back            depth += 1
        logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
logging.basicConfig(handlers=[InterceptHandler()], level=0)

[14] 方便的解析器

  • 從生成的日志中提取特定的信息通常很有用,這就是為什么Loguru提供了一個(gè)parse()方法來幫助處理日志和正則表達(dá)式。

pattern = r"(?Pcaster_dict = dict(time=dateutil.parser.parse, level=int)        # Transform matching groups
for groups in logger.parse("file.log", pattern, cast=caster_dict):    print("Parsed:", groups)    # {"level": 30, "message": "Log example", "time": datetime(2018, 12, 09, 11, 23, 55)}

[15] 通知機(jī)制

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

[16] Flask 框架集成

  • 現(xiàn)在最關(guān)鍵的一個(gè)問題是如何兼容別的logger,比如說tornado或者django有一些默認(rèn)的logger

  • 經(jīng)過研究,最好的解決方案是參考官方文檔的,完全整合logging的工作方式。比如下面將所有的logging都用logurulogger再發(fā)送一遍消息。

import loggingimport sys
from pathlib import Path
from flask import Flaskfrom loguru import logger
app = Flask(__name__)
class InterceptHandler(logging.Handler):    def emit(self, record):        logger_opt = logger.opt(depth=6, exception=record.exc_info)        logger_opt.log(record.levelname, record.getMessage())
def configure_logging(flask_app: Flask):    """配置日志"""    path = Path(flask_app.config['LOG_PATH'])    if not path.exists():        path.mkdir(parents=True)    log_name = Path(path, 'sips.log')
    logging.basicConfig(handlers=[InterceptHandler(level='INFO')], level='INFO')    # 配置日志到標(biāo)準(zhǔn)輸出流    logger.configure(handlers=[{"sink": sys.stderr, "level": 'INFO'}])    # 配置日志到輸出到文件    logger.add(log_name, rotation="500 MB", encoding='utf-8', colorize=False, level='INFO')

4. 要點(diǎn)解析

介紹,主要函數(shù)的使用方法和細(xì)節(jié) - add()的創(chuàng)建和刪除

  • add() - 非常重要的參數(shù)sink參數(shù)

    • 具體的實(shí)現(xiàn)規(guī)范可以參見官方文檔

    • 可以實(shí)現(xiàn)自定義Handler的配置,比如FileHandlerStreamHandler等等

    • 可以自行定義輸出實(shí)現(xiàn)

    • 代表文件路徑,會自動創(chuàng)建對應(yīng)路徑的日志文件并將日志輸出進(jìn)去

    • 例如sys.stderr或者open('file.log', 'w')都可以

    • 可以傳入一個(gè)file對象

    • 可以直接傳入一個(gè)str字符串或者pathlib.Path對象

    • 可以是一個(gè)方法

    • 可以是一個(gè)logging模塊的Handler

    • 可以是一個(gè)自定義的類

def add(self, sink, *,    level=_defaults.LOGURU_LEVEL, format=_defaults.LOGURU_FORMAT,    filter=_defaults.LOGURU_FILTER, colorize=_defaults.LOGURU_COLORIZE,    serialize=_defaults.LOGURU_SERIALIZE, backtrace=_defaults.LOGURU_BACKTRACE,    diagnose=_defaults.LOGURU_DIAGNOSE, enqueue=_defaults.LOGURU_ENQUEUE,    catch=_defaults.LOGURU_CATCH, **kwargs):
  • 另外添加sink之后我們也可以對其進(jìn)行刪除,相當(dāng)于重新刷新并寫入新的內(nèi)容。刪除的時(shí)候根據(jù)剛剛add方法返回的id進(jìn)行刪除即可。可以發(fā)現(xiàn),在調(diào)用remove方法之后,確實(shí)將歷史log刪除了。但實(shí)際上這并不是刪除,只不過是將sink對象移除之后,在這之前的內(nèi)容不會再輸出到日志中,這樣我們就可以實(shí)現(xiàn)日志的刷新重新寫入操作

from loguru import logger
trace = logger.add('runtime.log')logger.debug('this is a debug message')logger.remove(trace)logger.debug('this is another debug message')

原文鏈接:https://www.escapelife.site/posts/d4521b7.html

責(zé)任編輯:haq
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 輸出
    +關(guān)注

    關(guān)注

    0

    文章

    93

    瀏覽量

    22038
  • 日志
    +關(guān)注

    關(guān)注

    0

    文章

    140

    瀏覽量

    10779
  • python
    +關(guān)注

    關(guān)注

    56

    文章

    4821

    瀏覽量

    85679

原文標(biāo)題:使用loguru優(yōu)雅的輸出日志

文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    基于RV1126開發(fā)板限制系統(tǒng)日志大小教程

    無論管理什么系統(tǒng),對日志文件的監(jiān)控、調(diào)用、管理都是其中重要的一部分。服務(wù)器問題的解決都是從查看系統(tǒng)(錯(cuò)誤)日志開始的。系統(tǒng)日志記錄系統(tǒng)硬件狀況、內(nèi)核動作、軟件啟動、用戶動作等各項(xiàng)信息
    的頭像 發(fā)表于 04-16 11:18 ?73次閱讀
    基于RV1126開發(fā)板限制系統(tǒng)<b class='flag-5'>日志</b>大小教程

    云翎智能單北斗執(zhí)法記錄儀的AI智能識別與云端協(xié)同解決方案

    -云端智判-高效協(xié)同”的一體化解決方案。云翎智能單北斗工作記錄儀一、方案核心架構(gòu):北斗+AI+云端的深度融合云翎智能單北斗執(zhí)法記錄儀通過“厘米級定位+實(shí)時(shí)AI識別+云
    的頭像 發(fā)表于 04-08 11:35 ?147次閱讀
    云翎智能單北斗執(zhí)法<b class='flag-5'>記錄</b>儀的AI智能識別與云端協(xié)同<b class='flag-5'>解決方案</b>

    通信基站中 SMA 插頭的防松解決方案

    未來,我們德索工程師團(tuán)隊(duì)將繼續(xù)秉持對品質(zhì)的執(zhí)著追求,不斷探索技術(shù)創(chuàng)新,為通信基站行業(yè)提供更優(yōu)質(zhì)、更可靠的SMA插頭產(chǎn)品及防松解決方案,助力通信行業(yè)邁向新的高度。?
    的頭像 發(fā)表于 04-03 09:31 ?120次閱讀
    通信基站中 SMA 插頭的防松<b class='flag-5'>解決方案</b>

    Python Connector for InterBase連接解決方案

    適用于 InterBase 的 Python 連接器 Python Connector for InterBase 是一種可靠的連接解決方案,用于從 Python 應(yīng)用程序訪問 Int
    的頭像 發(fā)表于 01-22 14:34 ?285次閱讀

    適用于MySQL和MariaDB的Python連接器:可靠的MySQL數(shù)據(jù)連接器和數(shù)據(jù)庫

    適用于 MySQL 和 MariaDB 的 Python 連接器 Python Connector for MySQL 是一種可靠的連接解決方案,用于從 Python 應(yīng)用程序訪問 M
    的頭像 發(fā)表于 01-17 12:18 ?314次閱讀
    適用于MySQL和MariaDB的<b class='flag-5'>Python</b>連接器:可靠的MySQL數(shù)據(jù)連接器和數(shù)據(jù)庫

    Linux實(shí)時(shí)查看日志的四種命令詳解

    tail命令 - 實(shí)時(shí)監(jiān)控日志 如上所述,tail命令是實(shí)時(shí)顯示日志文件的最常用解決方案。但是,顯示該文件的命令有兩個(gè)版本,如下面的示例所示。 在第一個(gè)示例中,命令tail需要-f參數(shù)來跟蹤文件的內(nèi)容
    的頭像 發(fā)表于 01-13 10:45 ?1882次閱讀
    Linux實(shí)時(shí)查看<b class='flag-5'>日志</b>的四種命令詳解

    玩轉(zhuǎn)Nginx日志管理:高效排查問題的終極指南

    的處理時(shí)間等信息。錯(cuò)誤日志記錄了訪問出錯(cuò)的信息,可以幫助我們定位錯(cuò)誤的原因。 訪問日志主要記錄客戶端的請求。客戶端向Nginx服務(wù)器發(fā)起的每一次請求都
    的頭像 發(fā)表于 12-30 13:50 ?445次閱讀

    nginx日志配置方法

    access_log用來定義日志級別,日志位置。
    的頭像 發(fā)表于 10-24 17:43 ?435次閱讀

    Linux日志管理經(jīng)驗(yàn)總結(jié)

    日志內(nèi)容,合理的日志內(nèi)容(日志錨點(diǎn),內(nèi)容格式,等)可以為應(yīng)用服務(wù)的執(zhí)行記錄、問題排查提供最有力的幫助。
    的頭像 發(fā)表于 10-24 17:36 ?403次閱讀

    日志篇:模組日志總體介紹

    ?今天我們學(xué)習(xí)合宙模組日志總體介紹,以下進(jìn)入正文。 一、本文討論的邊界 本文是對合宙 4G 模組, 以及 4G+GNSS 模組的日志功能的總體介紹。通過日志,可以對研發(fā)過程中,以及模組運(yùn)行過程中
    的頭像 發(fā)表于 10-24 07:16 ?418次閱讀
    <b class='flag-5'>日志</b>篇:模組<b class='flag-5'>日志</b>總體介紹

    使用Python構(gòu)建高效的HTTP代理服務(wù)器

    構(gòu)建一個(gè)高效的HTTP代理服務(wù)器在Python中涉及多個(gè)方面,包括性能優(yōu)化、并發(fā)處理、協(xié)議支持(HTTP/HTTPS)、錯(cuò)誤處理以及日志記錄等。
    的頭像 發(fā)表于 10-23 07:41 ?380次閱讀

    Jtti:如何查看yum命令的錯(cuò)誤日志來診斷問題?

    在Linux系統(tǒng)中,當(dāng)yum命令無法正常工作時(shí),查看錯(cuò)誤日志是診斷問題的重要步驟。以下是一些方法,可以幫助你查看和分析yum命令的錯(cuò)誤日志: 查看Yum歷史記錄 : 你可以通過 yum
    的頭像 發(fā)表于 10-14 15:51 ?530次閱讀

    日志框架簡介-Slf4j+Logback入門實(shí)踐

    前言 隨著互聯(lián)網(wǎng)和大數(shù)據(jù)的迅猛發(fā)展,分布式日志系統(tǒng)和日志分析系統(tǒng)已廣泛應(yīng)用,幾乎所有應(yīng)用程序都使用各種日志框架記錄程序運(yùn)行信息。因此,作為工程師,了解主流的
    的頭像 發(fā)表于 07-30 10:00 ?1331次閱讀
    <b class='flag-5'>日志</b>框架簡介-Slf4j+Logback入門實(shí)踐

    奇怪!應(yīng)用的日志呢??

    1. 問題回顧 問題背景 是在進(jìn)行中臺應(yīng)用中間件遷移過程中,發(fā)現(xiàn)存在 項(xiàng)目啟動失敗 或者 項(xiàng)目正常啟動 (jsf正常掛載并正常運(yùn)行,mq正常發(fā)送和消費(fèi))但是 無任何日志打印 現(xiàn)象。 更奇怪 的是不打
    的頭像 發(fā)表于 06-11 10:48 ?449次閱讀
    奇怪!應(yīng)用的<b class='flag-5'>日志</b>呢??

    華為云開發(fā)者桌面全新發(fā)布 CodeArts IDE for Python,極致優(yōu)雅云原生開發(fā)體驗(yàn)

    Python 編碼體驗(yàn)。 Python 是一種編程語言,廣泛用于 Web 應(yīng)用程序、軟件開發(fā)、數(shù)據(jù)科學(xué)和機(jī)器學(xué)習(xí) (ML)。Python 以其優(yōu)雅的語法、動態(tài)解釋性、豐富的標(biāo)準(zhǔn)庫、極
    的頭像 發(fā)表于 05-10 00:27 ?1414次閱讀
    華為云開發(fā)者桌面全新發(fā)布 CodeArts IDE for <b class='flag-5'>Python</b>,極致<b class='flag-5'>優(yōu)雅</b>云原生開發(fā)體驗(yàn)
    主站蜘蛛池模板: 美女写真mm爽爽爽 | 久热操| 欧美日韩一区二区三区毛片 | 夜夜夜操操操 | 波多野结衣50连精喷在线 | 久久免费国产视频 | 伊人狼人综合 | 黄色片啪啪| 国产肥女bbwbbw | 一级毛片视屏 | 天堂网www在线资源网 | 视频在线观看网站免费 | 手机在线视频观看 | 欧美午夜影视 | 欧美在线视频播放 | 亚洲综合色丁香婷婷六月图片 | 性欧美黑人巨大videos | 国产福利午夜自产拍视频在线 | 天堂中文在线最新版地址 | 一色屋成人免费精品网站 | 男人的天堂在线免费视频 | 人操人操 | 美女很黄很黄是免费的·无遮挡网站 | 久操视屏 | 午夜免费福利网站 | a天堂在线观看 | 久久9热| 黄色在线免费看 | 国产精品夜夜春夜夜 | 5566成人免费视频观看 | 日韩有色 | 成人在线综合网 | 久久久久久免费播放一级毛片 | 色网综合| 一卡二卡三卡四卡无卡在线 | 性孕妇洗澡video国产 | 女的扒开尿口让男人桶爽 | 国产aaaaaaa毛片 | 美女视频网站色软件免费视频 | 久久久久综合中文字幕 | 午夜欧美精品久久久久久久 |