最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python使用logging實現(xiàn)多進程安全的日志模塊

 更新時間:2024年01月23日 08:07:43   作者:花酒鋤作田  
這篇文章主要為大家詳細介紹了Python如何使用標準庫logging實現(xiàn)多進程安全的日志模塊,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

前言

原本應用的日志是全部輸出到os的stdout,也就是控制臺輸出。因其它團隊要求也要保留日志文件,便于他們用其他工具統(tǒng)一采集,另一方面還要保留控制臺輸出,便于出問題的時候自己直接看pod日志。具體需求如下:

  • 日志支持同時控制臺輸出和文件輸出
  • 控制臺的輸出級別可以高點,比如WARNING,個人這邊的實際情況是WARNING或ERROR就能判斷大部分問題。日志文件的輸出級別設置為INFO,如果控制臺日志找不到問題,可以具體看日志文件的內(nèi)容。
  • 因為用到了多進程,所以寫文件的時候要保證多進程安全,避免日志內(nèi)容不會缺失。
  • 日志文件可以設置自動分割,避免長時間不清理導致硬盤存儲資源浪費。

因為不允許隨便使用第三方包,所以只能用標準庫的logging。一開始想的方法比較挫——對文件加鎖,但改來改去發(fā)現(xiàn)根本不能給別人review。翻python官方文檔的時候發(fā)現(xiàn)logging庫有個QueueHandlerQueueListener,簡單試了下感覺邏輯還算清楚,遂簡單整理了下代碼。

示例代碼

目錄結(jié)構(gòu)如下,main.py是入口腳本,logs目錄和app.log將有程序運行時自動生成,主要日志功能放在pkg/log.py文件中。pkg/__init__.py為空文件,僅用于標識為python包。

.
├── main.py
├── logs
│   └── app.log
└── pkg
    ├── __init__.py
    └── log.py

pkg/log.py內(nèi)容如下,主要提供logger已經(jīng)配置好的日志對象,該對象先將日志記錄到QueueHandler,然后QueueListener從隊列中取日志,并分別輸出到控制臺和日志文件中。close_log_queue()方法將在主進程結(jié)束時調(diào)用。

import logging
from logging.handlers import TimedRotatingFileHandler, QueueHandler, QueueListener
import sys
import os
# from queue import Queue
from multiprocessing import Queue

log_queue = Queue(-1)
queue_listener = ""


logdir = "logs"
logfile = f"{logdir}/app.log"
if not os.path.exists(logdir):
    os.makedirs(logdir, exist_ok=True)

def set_formatter():
    """設置日志格式化器"""
    fmt = "%(asctime)s | %(levelname)s | %(name)s | %(filename)s:%(lineno)d | %(funcName)s | %(message)s"
    datefmt = "%Y-%m-%d %H:%M:%S"
    return logging.Formatter(fmt, datefmt=datefmt)

def set_queue_handler():
    # 不要給QueueHandler重復設置formatter, 會引起重復嵌套
    handler = QueueHandler(log_queue)
    handler.setLevel(logging.INFO)
    return handler
def set_stream_handler(formatter: logging.Formatter):
    # 輸出到控制臺的日志處理器
    handler = logging.StreamHandler(sys.stdout)
    handler.setLevel(logging.WARNING)
    handler.setFormatter(formatter)
    return handler

def set_timed_rotating_file_handler(formatter: logging.Formatter):
    # 輸出到文件的日志處理器, 每天生成一個新文件, 最多保留10個文件
    handler = TimedRotatingFileHandler(logfile, when="midnight", backupCount=10, encoding="utf-8")
    handler.setLevel(logging.INFO)
    handler.setFormatter(formatter)
    return handler

def close_log_queue():
    # 關(guān)閉隊列監(jiān)聽器
    global queue_listener
    if queue_listener:
        queue_listener.stop()

def get_logger(name: str = "mylogger", level: int = logging.INFO):
    logger = logging.getLogger(name)
    logger.setLevel(level)

    formatter = set_formatter()

    stream_handler = set_stream_handler(formatter)
    file_handler = set_timed_rotating_file_handler(formatter)
    queue_handler = set_queue_handler()

    logger.addHandler(queue_handler)

    global queue_listener
    if not queue_listener:
        queue_listener = QueueListener(log_queue, stream_handler, file_handler, respect_handler_level=True)
        queue_listener.start()

    return logger


logger = get_logger()

if __name__ == "__main__":
    logger.info("test")
    close_log_queue()

main.py內(nèi)容如下,主要是創(chuàng)建子進程調(diào)用logger,觀察日志輸出是否正常。

from multiprocessing import Process
from pkg.log import logger, close_log_queue
import os

class MyProcess(Process):
    def __init__(self, delay):
        self.delay = delay
        super().__init__()

    def run(self):
        for i in range(self.delay):
            logger.info(f"pid: {os.getpid()}, {i}")

if __name__ == '__main__':
    logger.info(f"main process pid: {os.getpid()}")
    for i in range(10):
        p = MyProcess(10000)
        p.start()
        p.join()

    logger.info("main process end")
    close_log_queue()

執(zhí)行輸出大致如下所示:

$ tail logs/app.log 
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 1
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 2
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 3
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 4
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 5
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 6
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 7
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 8
2024-01-22 23:10:17 | INFO | mylogger | main.py:12 | run | pid: 7908, 9
2024-01-22 23:10:17 | INFO | mylogger | main.py:21 | <module> | main process end

補充

logging還內(nèi)置很多其它handler,比如按文件大小自動切割,日志通過HTTP請求輸出,日志輸出到syslog等,可按照自己需求進行定制。

到此這篇關(guān)于Python使用logging實現(xiàn)多進程安全的日志模塊的文章就介紹到這了,更多相關(guān)Python多進程安全的日志模塊內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python3中的globals()函數(shù)用法及說明

    Python3中的globals()函數(shù)用法及說明

    這篇文章主要介紹了Python3中的globals()函數(shù)用法及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-07-07
  • python中文字符如何轉(zhuǎn)url編碼

    python中文字符如何轉(zhuǎn)url編碼

    這篇文章主要介紹了python中文字符如何轉(zhuǎn)url編碼問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 用Python遠程登陸服務器的步驟

    用Python遠程登陸服務器的步驟

    這篇文章主要介紹了用Python遠程登陸服務器的步驟,幫助大家更好的理解和學習使用python,感興趣的朋友可以了解下
    2021-04-04
  • 離線安裝Pyecharts的步驟以及依賴包流程

    離線安裝Pyecharts的步驟以及依賴包流程

    這篇文章主要介紹了離線安裝Pyecharts的步驟以及依賴包流程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-03-03
  • python交互界面的退出方法

    python交互界面的退出方法

    今天小編就為大家分享一篇python交互界面的退出方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-02-02
  • Python抽象和自定義類定義與用法示例

    Python抽象和自定義類定義與用法示例

    這篇文章主要介紹了Python抽象和自定義類定義與用法,結(jié)合實例形式分析了Python抽象方法、抽象類相關(guān)功能、定義、用法及相關(guān)操作注意事項,需要的朋友可以參考下
    2018-08-08
  • 如何定時自啟動與自關(guān)閉一些python腳本

    如何定時自啟動與自關(guān)閉一些python腳本

    這篇文章主要介紹了如何定時自啟動與自關(guān)閉一些python腳本問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Pytorch使用VGG16模型進行預測貓狗二分類實戰(zhàn)

    Pytorch使用VGG16模型進行預測貓狗二分類實戰(zhàn)

    VGG16是Visual Geometry Group的縮寫,它的名字來源于提出該網(wǎng)絡的實驗室,本文我們將使用PyTorch來實現(xiàn)VGG16網(wǎng)絡,用于貓狗預測的二分類任務,我們將對VGG16的網(wǎng)絡結(jié)構(gòu)進行適當?shù)男薷?以適應我們的任務,需要的朋友可以參考下
    2023-08-08
  • python opencv之SIFT算法示例

    python opencv之SIFT算法示例

    這篇文章主要介紹了python opencv之SIFT算法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • matplotlib在python上繪制3D散點圖實例詳解

    matplotlib在python上繪制3D散點圖實例詳解

    這篇文章主要介紹了matplotlib在python上繪制3D散點圖實例詳解,首先介紹了官網(wǎng)的實例,然后分享了本文簡單代碼示例,具有一定借鑒價值,需要的朋友可以了解下。
    2017-12-12

最新評論

绩溪县| 信丰县| 霞浦县| 碌曲县| 孟连| 札达县| 天祝| 会东县| 太白县| 刚察县| 郓城县| 永济市| 密云县| 洛浦县| 河南省| 娱乐| 曲麻莱县| 合阳县| 黔江区| 汤原县| 同德县| 七台河市| 家居| 益阳市| 宜川县| 定南县| 舟曲县| 钦州市| 星座| 周口市| 洛南县| 永安市| 贵港市| 米脂县| 清流县| 资兴市| 楚雄市| 东宁县| 兰溪市| 梁山县| 宜昌市|