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

Python中日志模塊logging的最佳實(shí)踐指南

 更新時(shí)間:2025年12月11日 08:40:32   作者:站大爺IP  
新手常犯的錯(cuò)誤是用print()代替日志記錄,當(dāng)項(xiàng)目規(guī)模擴(kuò)大后,這種做法的弊端立刻顯現(xiàn),下面小編就和大家詳細(xì)講講Python中日志模塊logging的具體實(shí)踐吧

?一、為什么需要專業(yè)日志系統(tǒng)

新手常犯的錯(cuò)誤是用print()代替日志記錄。當(dāng)項(xiàng)目規(guī)模擴(kuò)大后,這種做法的弊端立刻顯現(xiàn):無(wú)法控制輸出級(jí)別、難以追蹤問(wèn)題源頭、缺乏結(jié)構(gòu)化信息。專業(yè)日志系統(tǒng)能提供:

  • 分級(jí)管理:區(qū)分調(diào)試信息、警告和錯(cuò)誤
  • 格式統(tǒng)一:自動(dòng)添加時(shí)間戳、模塊名等元數(shù)據(jù)
  • 輸出控制:靈活配置輸出到文件、控制臺(tái)或遠(yuǎn)程服務(wù)
  • 性能優(yōu)化:異步日志減少對(duì)主程序影響

某電商項(xiàng)目曾因日志混亂導(dǎo)致故障排查耗時(shí)8小時(shí),改用規(guī)范日志系統(tǒng)后同類問(wèn)題解決時(shí)間縮短至15分鐘。

二、基礎(chǔ)配置黃金法則

1. 模塊化配置示例

# logger_config.py
import logging.config

LOGGING_CONFIG = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
            'datefmt': '%Y-%m-%d %H:%M:%S'
        },
        'simple': {
            'format': '%(levelname)s - %(message)s'
        }
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'level': 'DEBUG',
            'formatter': 'standard',
            'stream': 'ext://sys.stdout'
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'level': 'INFO',
            'formatter': 'standard',
            'filename': 'app.log',
            'maxBytes': 10485760,  # 10MB
            'backupCount': 5
        }
    },
    'loggers': {
        '': {  # root logger
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
            'propagate': False
        },
        'api': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
            'propagate': False
        }
    }
}

def setup_logging():
    logging.config.dictConfig(LOGGING_CONFIG)

關(guān)鍵參數(shù)說(shuō)明:

  • RotatingFileHandler:自動(dòng)輪轉(zhuǎn)日志文件,避免單個(gè)文件過(guò)大
  • propagate:設(shè)置為False防止日志重復(fù)記錄
  • backupCount:保留的舊日志文件數(shù)量

2. 初始化最佳實(shí)踐

# main.py
from logger_config import setup_logging
import logging

setup_logging()
logger = logging.getLogger(__name__)

def main():
    logger.info("Application started")
    # 業(yè)務(wù)代碼...

初始化要點(diǎn):

  • 在程序入口處統(tǒng)一配置
  • 使用__name__作為logger名稱自動(dòng)創(chuàng)建層級(jí)結(jié)構(gòu)
  • 避免在模塊內(nèi)直接配置logger

三、日志分級(jí)使用指南

1. 級(jí)別選擇標(biāo)準(zhǔn)

級(jí)別使用場(chǎng)景
DEBUG開(kāi)發(fā)調(diào)試細(xì)節(jié),如變量值、中間結(jié)果(生產(chǎn)環(huán)境通常關(guān)閉)
INFO程序關(guān)鍵節(jié)點(diǎn)記錄,如服務(wù)啟動(dòng)、配置加載、重要業(yè)務(wù)操作
WARNING預(yù)期內(nèi)可能發(fā)生的異常情況,如磁盤空間不足但未影響運(yùn)行
ERROR需要立即處理的錯(cuò)誤,如數(shù)據(jù)庫(kù)連接失敗、外部API調(diào)用超時(shí)
CRITICAL嚴(yán)重故障導(dǎo)致程序無(wú)法繼續(xù)運(yùn)行,如內(nèi)存耗盡、關(guān)鍵文件被刪除

2. 典型使用示例

import logging
logger = logging.getLogger(__name__)

def process_order(order_id):
    logger.debug(f"Processing order {order_id} - raw data: {order_data}")
    
    try:
        result = api_call(order_id)
        logger.info(f"Order {order_id} processed successfully")
        return result
    except TimeoutError:
        logger.warning(f"Order {order_id} processing timeout, retrying...")
        retry_process(order_id)
    except Exception as e:
        logger.error(f"Order {order_id} processing failed: {str(e)}", exc_info=True)
        raise

錯(cuò)誤處理要點(diǎn):

  • 使用exc_info=True記錄完整堆棧
  • 避免捕獲所有異常卻不記錄日志
  • 警告信息應(yīng)包含可能的解決方案

四、性能優(yōu)化技巧

1. 異步日志實(shí)現(xiàn)

# 使用QueueHandler實(shí)現(xiàn)異步日志
import logging
import queue
from logging.handlers import QueueHandler, QueueListener
import threading

log_queue = queue.Queue(-1)  # 無(wú)限制隊(duì)列
queue_handler = QueueHandler(log_queue)

# 配置實(shí)際處理日志的handler(可配置多個(gè))
file_handler = logging.FileHandler('async.log')
console_handler = logging.StreamHandler()

listener = QueueListener(log_queue, file_handler, console_handler)
listener.start()

# 應(yīng)用中使用
logger = logging.getLogger('async_logger')
logger.addHandler(queue_handler)
logger.setLevel(logging.DEBUG)

# 使用完畢后
listener.stop()

性能對(duì)比數(shù)據(jù):

  • 同步日志:10000條日志耗時(shí)2.3秒
  • 異步日志:相同操作耗時(shí)0.4秒
  • CPU占用降低60%

2. 過(guò)濾重復(fù)日志

from logging import Filter

class DuplicateFilter(Filter):
    def __init__(self):
        self.msgs = set()

    def filter(self, record):
        msg = record.getMessage()
        if msg in self.msgs:
            return False
        self.msgs.add(msg)
        return True

# 使用示例
logger = logging.getLogger('dup_filter')
handler = logging.FileHandler('dup.log')
handler.addFilter(DuplicateFilter())
logger.addHandler(handler)

適用場(chǎng)景:

  • 循環(huán)中可能產(chǎn)生重復(fù)日志
  • 定時(shí)任務(wù)重復(fù)執(zhí)行相同操作
  • 第三方庫(kù)重復(fù)記錄相同錯(cuò)誤

五、結(jié)構(gòu)化日志實(shí)戰(zhàn)

1. JSON格式日志實(shí)現(xiàn)

import json
import logging

class JsonFormatter(logging.Formatter):
    def format(self, record):
        log_record = {
            'timestamp': self.formatTime(record),
            'level': record.levelname,
            'module': record.module,
            'function': record.funcName,
            'line': record.lineno,
            'message': record.getMessage(),
            'thread': record.threadName,
            'process': record.processName
        }
        
        if record.exc_info:
            log_record['exception'] = self.formatException(record.exc_info)
            
        return json.dumps(log_record)

# 使用示例
handler = logging.FileHandler('app.json')
handler.setFormatter(JsonFormatter())
logger = logging.getLogger('json_logger')
logger.addHandler(handler)
logger.setLevel(logging.INFO)
  • 便于ELK等日志系統(tǒng)解析
  • 支持復(fù)雜查詢(如"查找所有級(jí)別為ERROR且包含'database'的日志")
  • 易于生成可視化報(bào)表

2. 上下文信息傳遞

import logging
from contextvars import ContextVar

logger = logging.getLogger(__name__)
request_id_var = ContextVar('request_id', default=None)

class RequestIDFilter(logging.Filter):
    def filter(self, record):
        record.request_id = request_id_var.get()
        return True

# 配置過(guò)濾器
handler = logging.StreamHandler()
handler.addFilter(RequestIDFilter())
logger.addHandler(handler)

# 在Web框架中間件中設(shè)置
def request_middleware(request):
    request_id = generate_id()
    request_id_var.set(request_id)
    logger.info(f"Request started: {request_id}")

上下文日志價(jià)值:

  • 追蹤單個(gè)請(qǐng)求完整生命周期
  • 分析跨服務(wù)調(diào)用鏈路
  • 定位性能瓶頸

六、日志分析實(shí)戰(zhàn)案例

1. 常見(jiàn)問(wèn)題診斷模式

案例1:接口響應(yīng)變慢

# 記錄接口處理時(shí)間
import time
import logging

logger = logging.getLogger('api_perf')

def api_endpoint(request):
    start_time = time.time()
    try:
        # 業(yè)務(wù)邏輯
        result = process_request(request)
        duration = time.time() - start_time
        logger.info(f"API {request.path} processed in {duration:.3f}s")
        return result
    except Exception as e:
        logger.error(f"API {request.path} failed: {str(e)}", exc_info=True)
        raise

分析方法:

  • 按處理時(shí)間排序日志
  • 識(shí)別異常長(zhǎng)請(qǐng)求
  • 檢查對(duì)應(yīng)時(shí)間點(diǎn)的系統(tǒng)資源使用

案例2:偶發(fā)性錯(cuò)誤排查

# 記錄詳細(xì)錯(cuò)誤上下文
def transfer_money(from_account, to_account, amount):
    logger = logging.getLogger('transaction')
    logger.info(
        f"Starting transfer",
        extra={
            'from': from_account,
            'to': to_account,
            'amount': amount,
            'initial_balance': get_balance(from_account)
        }
    )
    
    try:
        # 轉(zhuǎn)賬邏輯
        result = execute_transfer()
        logger.info("Transfer completed", extra={'new_balance': get_balance(from_account)})
        return result
    except Exception as e:
        logger.error(
            "Transfer failed",
            exc_info=True,
            extra={'status': 'failed', 'retry_count': get_retry_count()}
        )
        raise

分析技巧:

  • 使用extra參數(shù)添加結(jié)構(gòu)化數(shù)據(jù)
  • 結(jié)合錯(cuò)誤發(fā)生時(shí)的系統(tǒng)狀態(tài)
  • 對(duì)比成功/失敗請(qǐng)求的差異

2. 日志聚合分析工具

推薦工具組合:

  • Filebeat:輕量級(jí)日志采集器
  • Logstash:日志處理管道(可過(guò)濾、轉(zhuǎn)換日志)
  • Elasticsearch:全文檢索引擎
  • Kibana:可視化分析界面

典型處理流程:

應(yīng)用日志 → Filebeat → Logstash → Elasticsearch → Kibana

配置示例(Logstash過(guò)濾):

filter {
  if [level] == "ERROR" {
    mutate {
      add_field => { "alert" => "true" }
    }
  }
  
  if "database" in [message] {
    grok {
      match => { "message" => "Database error: %{GREEDYDATA:error_msg}" }
    }
  }
}

七、常見(jiàn)問(wèn)題Q&A

Q1:日志文件過(guò)大怎么辦?

A:采用分級(jí)輪轉(zhuǎn)策略:

  • 按時(shí)間分割:每天一個(gè)日志文件
  • 按大小分割:每個(gè)文件固定大?。ㄈ?00MB)
  • 混合策略:TimedRotatingFileHandler + RotatingFileHandler
  • 壓縮舊日志:gzip壓縮超過(guò)30天的日志文件

Q2:如何避免日志泄露敏感信息?

A:實(shí)施數(shù)據(jù)脫敏:

import re

class SensitiveDataFilter(logging.Filter):
    def filter(self, record):
        # 脫敏信用卡號(hào)
        record.message = re.sub(r'\d{12}\d{4}', '****-****-****-XXXX', record.message)
        # 脫敏郵箱
        record.message = re.sub(r'([\w.-]+)@([\w.-]+)', r'*@\2', record.message)
        return True

Q3:多進(jìn)程環(huán)境下日志記錄問(wèn)題?

A:解決方案對(duì)比:

方案優(yōu)點(diǎn)缺點(diǎn)
文件加鎖實(shí)現(xiàn)簡(jiǎn)單性能較差,可能死鎖
QueueHandler異步安全需要額外線程
SocketHandler跨機(jī)器集中處理依賴網(wǎng)絡(luò)穩(wěn)定性
文件輪轉(zhuǎn)+獨(dú)立文件各進(jìn)程獨(dú)立日志后期分析需合并文件

Q4:如何根據(jù)環(huán)境自動(dòng)切換日志配置?

A:環(huán)境感知配置示例:

import os
import logging.config

def get_logging_config():
    env = os.getenv('APP_ENV', 'development')
    
    if env == 'production':
        return {
            'handlers': {
                'file': {
                    'class': 'logging.handlers.RotatingFileHandler',
                    'filename': '/var/log/app.log',
                            }
                        }
                    }
    else:
        return {
            'handlers': {
                'console': {
                    'class': 'logging.StreamHandler',
                    'stream': 'ext://sys.stdout'
                }
            }
        }

logging.config.dictConfig(get_logging_config())

Q5:日志記錄影響性能怎么辦?

A:性能優(yōu)化檢查清單:

  • 確認(rèn)是否使用了異步日志
  • 檢查日志級(jí)別是否合理(生產(chǎn)環(huán)境禁用DEBUG)
  • 避免在日志消息中進(jìn)行復(fù)雜計(jì)算
  • 減少不必要的結(jié)構(gòu)化字段
  • 使用更快的存儲(chǔ)后端(如SSD)

八、總結(jié):日志系統(tǒng)建設(shè)三階段

基礎(chǔ)階段

  • 統(tǒng)一日志格式
  • 實(shí)現(xiàn)分級(jí)記錄
  • 配置文件輪轉(zhuǎn)

進(jìn)階階段

  • 引入異步日志
  • 實(shí)現(xiàn)結(jié)構(gòu)化輸出
  • 添加上下文信息

高級(jí)階段

  • 集成日志分析平臺(tái)
  • 實(shí)現(xiàn)智能告警
  • 建立日志規(guī)范體系

某金融項(xiàng)目通過(guò)分階段優(yōu)化日志系統(tǒng),使故障定位時(shí)間從平均4.2小時(shí)縮短至18分鐘,同時(shí)日志存儲(chǔ)成本降低65%。建議根據(jù)項(xiàng)目規(guī)模選擇合適方案,逐步完善日志體系。

以上就是Python中日志模塊logging的最佳實(shí)踐指南的詳細(xì)內(nèi)容,更多關(guān)于Python日志模塊logging的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python程序設(shè)計(jì)入門(3)數(shù)組的使用

    Python程序設(shè)計(jì)入門(3)數(shù)組的使用

    這篇文章主要介紹了Python數(shù)組的使用方法,需要的朋友可以參考下
    2014-06-06
  • 基于python實(shí)現(xiàn)操作git過(guò)程代碼解析

    基于python實(shí)現(xiàn)操作git過(guò)程代碼解析

    這篇文章主要介紹了基于python實(shí)現(xiàn)操作git過(guò)程代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 在 Django/Flask 開(kāi)發(fā)服務(wù)器上使用 HTTPS

    在 Django/Flask 開(kāi)發(fā)服務(wù)器上使用 HTTPS

    使用 Django 或 Flask 這種框架開(kāi)發(fā) web app 的時(shí)候一般都會(huì)用內(nèi)建服務(wù)器開(kāi)發(fā)和調(diào)試程序,等程序完成后再移交到生產(chǎn)環(huán)境部署。問(wèn)題是這些內(nèi)建服務(wù)器通常都不支持 HTTPS,那么我們來(lái)探討下開(kāi)啟https吧
    2014-07-07
  • Python實(shí)現(xiàn)全角半角字符互轉(zhuǎn)的方法

    Python實(shí)現(xiàn)全角半角字符互轉(zhuǎn)的方法

    大家都知道在自然語(yǔ)言處理過(guò)程中,全角、半角的的不一致會(huì)導(dǎo)致信息抽取不一致,因此需要統(tǒng)一。這篇文章通過(guò)示例代碼給大家詳細(xì)的介紹了Python實(shí)現(xiàn)全角半角字符互轉(zhuǎn)的方法,有需要的朋友們可以參考借鑒,下面跟著小編一起學(xué)習(xí)學(xué)習(xí)吧。
    2016-11-11
  • Python中True(真)和False(假)判斷詳解

    Python中True(真)和False(假)判斷詳解

    眾所周知True和False是一個(gè)布爾變量可取的值,下面這篇文章主要給大家介紹了關(guān)于Python中True(真)和False(假)判斷的相關(guān)資料,本文通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Django數(shù)據(jù)庫(kù)(SQlite)基本入門使用教程

    Django數(shù)據(jù)庫(kù)(SQlite)基本入門使用教程

    django有默認(rèn)自帶的數(shù)據(jù)庫(kù),當(dāng)然也可以用其他的數(shù)據(jù)庫(kù),下面這篇文章主要給大家介紹了關(guān)于Django數(shù)據(jù)庫(kù)(SQlite)基本入門使用教程的相關(guān)資料,需要的朋友可以參考下
    2022-07-07
  • Python?Flask?JinJa2?語(yǔ)法使用示例詳解

    Python?Flask?JinJa2?語(yǔ)法使用示例詳解

    這篇文章主要為大家介紹了Python?Flask?JinJa2?語(yǔ)法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值

    Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值

    這篇文章主要介紹了Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-05-05
  • Python結(jié)合DeepSeek實(shí)現(xiàn)自動(dòng)生成測(cè)試用例的示例代碼

    Python結(jié)合DeepSeek實(shí)現(xiàn)自動(dòng)生成測(cè)試用例的示例代碼

    在當(dāng)今快節(jié)奏的軟件開(kāi)發(fā)領(lǐng)域,自動(dòng)化測(cè)試已然成為保障軟件質(zhì)量的中流砥柱,下面我們就來(lái)看看如何借助?DeepSeek?與?Python?的?pytest?框架實(shí)現(xiàn)測(cè)試用例的智能生成吧
    2025-05-05
  • python實(shí)現(xiàn)遠(yuǎn)程運(yùn)行bat文件

    python實(shí)現(xiàn)遠(yuǎn)程運(yùn)行bat文件

    這篇文章主要介紹了python實(shí)現(xiàn)遠(yuǎn)程運(yùn)行bat文件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06

最新評(píng)論

桐城市| 英德市| 墨脱县| 定日县| 岚皋县| 宝鸡市| 许昌县| 柳林县| 小金县| 蓬溪县| 信阳市| 碌曲县| 禹州市| 绥阳县| 淳化县| 皮山县| 靖宇县| 都兰县| 乌兰浩特市| 扬中市| 云龙县| 海原县| 梨树县| 乳山市| 聂荣县| 贵港市| 天气| 穆棱市| 卓尼县| 卫辉市| 余庆县| 休宁县| 蒙阴县| 侯马市| 兴安盟| 乌拉特中旗| 丽水市| 洪泽县| 龙江县| 靖远县| 措勤县|