自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Python 日志記錄:十個(gè)日志管理的最佳實(shí)踐

開(kāi)發(fā) 后端
本文介紹了 十個(gè) Python 日志管理的優(yōu)秀實(shí)踐,通過(guò)這些技巧,你可以更好地管理和優(yōu)化你的日志記錄系統(tǒng)。

日志記錄是軟件開(kāi)發(fā)中的一個(gè)重要組成部分,它可以幫助開(kāi)發(fā)者調(diào)試程序、追蹤錯(cuò)誤、監(jiān)控系統(tǒng)狀態(tài)等。Python 提供了強(qiáng)大的日志記錄功能,通過(guò) logging 模塊可以輕松實(shí)現(xiàn)各種日志管理需求。本文將介紹 10 個(gè) Python 日志管理的最佳實(shí)踐,并通過(guò)實(shí)際代碼示例幫助你更好地理解和應(yīng)用這些技巧。

1. 使用 logging 模塊的基本配置

首先,我們需要了解如何使用 logging 模塊的基本配置。logging 模塊提供了多種級(jí)別的日志記錄,包括 DEBUG、INFO、WARNING、ERROR 和 CRITICAL。

import logging

# 配置日志記錄
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

# 記錄不同級(jí)別的日志
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')

輸出結(jié)果:

2023-10-01 12:00:00,000 - DEBUG - This is a debug message
2023-10-01 12:00:00,001 - INFO - This is an info message
2023-10-01 12:00:00,002 - WARNING - This is a warning message
2023-10-01 12:00:00,003 - ERROR - This is an error message
2023-10-01 12:00:00,004 - CRITICAL - This is a critical message

2. 將日志記錄到文件

除了將日志輸出到控制臺(tái),我們還可以將日志記錄到文件中,以便長(zhǎng)期保存和分析。

import logging

# 配置日志記錄到文件
logging.basicConfig(filename='app.log', level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')

# 記錄日志
logging.debug('This is a debug message')
logging.info('This is an info message')

輸出結(jié)果:

# app.log 文件內(nèi)容
2023-10-01 12:00:00,000 - DEBUG - This is a debug message
2023-10-01 12:00:00,001 - INFO - This is an info message

3. 使用多個(gè)日志處理器

有時(shí)候我們需要同時(shí)將日志輸出到控制臺(tái)和文件中,這時(shí)可以使用多個(gè)日志處理器(Handler)。

import logging

# 創(chuàng)建日志記錄器
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 創(chuàng)建控制臺(tái)處理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter('%(levelname)s - %(message)s')
console_handler.setFormatter(console_formatter)

# 添加處理器到日志記錄器
logger.addHandler(file_handler)
logger.addHandler(console_handler)

# 記錄日志
logger.debug('This is a debug message')
logger.info('This is an info message')
logger.error('This is an error message')

輸出結(jié)果:

# 控制臺(tái)輸出
INFO - This is an info message
ERROR - This is an error message

# app.log 文件內(nèi)容
2023-10-01 12:00:00,000 - DEBUG - This is a debug message
2023-10-01 12:00:00,001 - INFO - This is an info message
2023-10-01 12:00:00,002 - ERROR - This is an error message

4. 使用日志過(guò)濾器

日志過(guò)濾器可以用來(lái)過(guò)濾特定的日志消息,例如只記錄特定模塊的日志。

import logging

# 創(chuàng)建日志記錄器
logger = logging.getLogger('my_module')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('my_module.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 創(chuàng)建過(guò)濾器
class ModuleFilter(logging.Filter):
    def filter(self, record):
        return 'my_module' in record.name

file_handler.addFilter(ModuleFilter())

# 添加處理器到日志記錄器
logger.addHandler(file_handler)

# 記錄日志
logger.debug('This is a debug message from my_module')
logging.getLogger().info('This is an info message from root logger')

輸出結(jié)果:

# my_module.log 文件內(nèi)容
2023-10-01 12:00:00,000 - my_module - DEBUG - This is a debug message from my_module

5. 使用日志記錄器的層級(jí)結(jié)構(gòu)

logging 模塊支持日志記錄器的層級(jí)結(jié)構(gòu),可以通過(guò)父級(jí)記錄器的配置影響子級(jí)記錄器。

import logging

# 創(chuàng)建父級(jí)日志記錄器
parent_logger = logging.getLogger('parent')
parent_logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('parent.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 添加處理器到父級(jí)日志記錄器
parent_logger.addHandler(file_handler)

# 創(chuàng)建子級(jí)日志記錄器
child_logger = logging.getLogger('parent.child')
child_logger.setLevel(logging.INFO)

# 記錄日志
child_logger.debug('This is a debug message from child')

輸出結(jié)果:

# parent.log 文件內(nèi)容
2023-10-01 12:00:00,000 - parent.child - INFO - This is an info message from child

6. 使用日志記錄器的命名空間

通過(guò)命名空間可以更好地組織和管理日志記錄器,避免命名沖突。

import logging

# 創(chuàng)建命名空間日志記錄器
logger = logging.getLogger('my_app.module1')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('module1.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 添加處理器到日志記錄器
logger.addHandler(file_handler)

# 記錄日志
logger.debug('This is a debug message from module1')

輸出結(jié)果:

# module1.log 文件內(nèi)容
2023-10-01 12:00:00,000 - my_app.module1 - DEBUG - This is a debug message from module1

7. 使用日志記錄器的上下文信息

通過(guò) extra 參數(shù)可以在日志記錄時(shí)添加額外的上下文信息。

import logging

# 創(chuàng)建日志記錄器
logger = logging.getLogger('context_logger')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('context.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(user)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 添加處理器到日志記錄器
logger.addHandler(file_handler)

# 記錄日志
logger.info('This is an info message', extra={'user': 'Alice'})

輸出結(jié)果:

# context.log 文件內(nèi)容
2023-10-01 12:00:00,000 - context_logger - INFO - Alice - This is an info message

8. 使用日志記錄器的異步處理

對(duì)于高并發(fā)的應(yīng)用,可以使用異步處理來(lái)提高日志記錄的性能。

import logging
import queue
import threading

# 創(chuàng)建隊(duì)列
log_queue = queue.Queue()

# 創(chuàng)建日志記錄器
logger = logging.getLogger('async_logger')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建文件處理器
file_handler = logging.FileHandler('async.log')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 定義異步處理函數(shù)
def process_logs():
    while True:
        record = log_queue.get()
        if record is None:
            break
        file_handler.emit(record)

# 啟動(dòng)異步處理線程
thread = threading.Thread(target=process_logs)
thread.start()

# 自定義日志處理器
class QueueHandler(logging.Handler):
    def emit(self, record):
        log_queue.put_nowait(record)

# 添加自定義處理器到日志記錄器
queue_handler = QueueHandler()
logger.addHandler(queue_handler)

# 記錄日志
logger.debug('This is a debug message')
logger.info('This is an info message')

# 停止異步處理線程
log_queue.put(None)
thread.join()

輸出結(jié)果:

# async.log 文件內(nèi)容
2023-10-01 12:00:00,000 - async_logger - DEBUG - This is a debug message
2023-10-01 12:00:00,001 - async_logger - INFO - This is an info message

9. 使用日志記錄器的輪轉(zhuǎn)日志

輪轉(zhuǎn)日志可以自動(dòng)管理日志文件的大小和數(shù)量,避免日志文件過(guò)大或過(guò)多。

import logging
from logging.handlers import RotatingFileHandler

# 創(chuàng)建日志記錄器
logger = logging.getLogger('rotating_logger')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建輪轉(zhuǎn)文件處理器
file_handler = RotatingFileHandler('rotating.log', maxBytes=1024, backupCount=5)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 添加處理器到日志記錄器
logger.addHandler(file_handler)

# 記錄日志
for i in range(100):
    logger.debug(f'This is a debug message {i}')

輸出結(jié)果:

# rotating.log 文件內(nèi)容
2023-10-01 12:00:00,000 - rotating_logger - DEBUG - This is a debug message 0
2023-10-01 12:00:00,001 - rotating_logger - DEBUG - This is a debug message 1
...
2023-10-01 12:00:00,099 - rotating_logger - DEBUG - This is a debug message 99

10. 使用日志記錄器的定時(shí)任務(wù)

定時(shí)任務(wù)可以定期清理或歸檔日志文件,保持系統(tǒng)的整潔。

import logging
import time
from logging.handlers import TimedRotatingFileHandler

# 創(chuàng)建日志記錄器
logger = logging.getLogger('timed_logger')
logger.setLevel(logging.DEBUG)

# 創(chuàng)建定時(shí)輪轉(zhuǎn)文件處理器
file_handler = TimedRotatingFileHandler('timed.log', when='S', interval=10, backupCount=5)
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(file_formatter)

# 添加處理器到日志記錄器
logger.addHandler(file_handler)

# 記錄日志
for i in range(60):
    logger.debug(f'This is a debug message {i}')
    time.sleep(1)

輸出結(jié)果:

# timed.log 文件內(nèi)容
2023-10-01 12:00:00,000 - timed_logger - DEBUG - This is a debug message 0
2023-10-01 12:00:01,000 - timed_logger - DEBUG - This is a debug message 1
...
2023-10-01 12:01:00,000 - timed_logger - DEBUG - This is a debug message 59

實(shí)戰(zhàn)案例:日志記錄在 Web 應(yīng)用中的應(yīng)用

假設(shè)我們有一個(gè)簡(jiǎn)單的 Flask Web 應(yīng)用,需要記錄用戶(hù)的訪問(wèn)日志和錯(cuò)誤日志。我們將使用 logging 模塊來(lái)實(shí)現(xiàn)這一需求。

from flask import Flask, request, jsonify
import logging
from logging.handlers import RotatingFileHandler

app = Flask(__name__)

# 配置日志記錄
access_logger = logging.getLogger('access_logger')
access_logger.setLevel(logging.INFO)

error_logger = logging.getLogger('error_logger')
error_logger.setLevel(logging.ERROR)

# 創(chuàng)建輪轉(zhuǎn)文件處理器
access_file_handler = RotatingFileHandler('access.log', maxBytes=1024*1024, backupCount=5)
access_file_handler.setLevel(logging.INFO)
access_formatter = logging.Formatter('%(asctime)s - %(remote_addr)s - %(request_method)s - %(path)s - %(status_code)s')
access_file_handler.setFormatter(access_formatter)

error_file_handler = RotatingFileHandler('error.log', maxBytes=1024*1024, backupCount=5)
error_file_handler.setLevel(logging.ERROR)
error_formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
error_file_handler.setFormatter(error_formatter)

# 添加處理器到日志記錄器
access_logger.addHandler(access_file_handler)
error_logger.addHandler(error_file_handler)

@app.before_request
def log_access():
    remote_addr = request.remote_addr
    request_method = request.method
    path = request.path
    access_logger.info('', extra={'remote_addr': remote_addr, 'request_method': request_method, 'path': path, 'status_code': 200})

@app.errorhandler(Exception)
def handle_error(e):
    error_logger.error(str(e))
    return jsonify({'error': str(e)}), 500

@app.route('/')
def index():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(debug=True)

輸出結(jié)果:

# access.log 文件內(nèi)容
2023-10-01 12:00:00,000 - 127.0.0.1 - GET - / - 200

# error.log 文件內(nèi)容
2023-10-01 12:00:00,000 - ERROR - Some unexpected error occurred

總結(jié)

本文介紹了 10 個(gè) Python 日志管理的最佳實(shí)踐,包括基本配置、日志記錄到文件、使用多個(gè)日志處理器、日志過(guò)濾器、日志記錄器的層級(jí)結(jié)構(gòu)、命名空間、上下文信息、異步處理、輪轉(zhuǎn)日志和定時(shí)任務(wù)。通過(guò)這些技巧,你可以更好地管理和優(yōu)化你的日志記錄系統(tǒng)。最后,我們還通過(guò)一個(gè)實(shí)戰(zhàn)案例展示了如何在 Flask Web 應(yīng)用中應(yīng)用這些技巧。

責(zé)任編輯:趙寧寧 來(lái)源: 手把手PythonAI編程
相關(guān)推薦

2023-09-12 06:55:27

2025-03-18 00:10:00

2012-10-29 09:30:47

HadoopHadoop集群Hadoop生態(tài)系統(tǒng)包

2012-09-03 10:33:43

2024-01-06 18:02:18

編程記錄日志

2023-05-24 12:33:35

2020-06-10 09:57:23

Kubernetes日志容器

2015-06-24 10:07:34

Java編碼最佳實(shí)踐

2024-11-21 17:22:40

2010-09-28 17:38:56

日志管理

2010-08-11 15:09:15

2023-12-06 07:13:16

RESTAPI客戶(hù)端

2024-09-23 00:00:00

下拉菜單UI控件

2012-09-03 10:39:13

Hadoop管理員

2024-04-08 14:33:18

2022-11-02 12:17:41

2017-03-06 13:20:31

2024-03-14 11:15:58

DevOpsPipeline軟件

2021-10-25 14:40:43

Web工具Linux

2023-08-03 00:06:21

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)