日志记录测试

Posted by Shallow Dreameron January 9, 2025

如果你的目标是将日志记录操作更加简洁地集成到 Django 视图和内部函数中,而不需要额外的中间件或复杂配置,可以通过以下方式实现:

方案:简化的日志记录方案

我们可以利用 loggingloggerlogger.debug 方法,同时结合 UserLogFilter,使得在视图内部及内部函数中记录日志时,无需额外传递或配置 request 对象,且能够直接根据用户动态生成日志文件。

这种方式的关键点在于:

  • 自动化文件生成:通过日志过滤器 UserLogFilter 来自动根据用户生成日志文件路径。
  • 简化配置:避免使用中间件,而是在每个视图内部直接记录日志。

1. 修改 UserLogFilter 使其简洁并自动处理请求

这里的目标是利用 logginglogger 自动完成路径配置,而不需要在每个视图函数中传递 request。为了简化操作,我们将会在 filter 中直接处理请求对象,确保请求对象能够被自动传递。

创建简洁的日志过滤器 UserLogFilter

import logging
import os
from django.utils.timezone import now

class UserLogFilter(logging.Filter):
    def filter(self, record):
        # 自动获取当前请求的用户信息
        request = getattr(record, 'request', None)
        user = request.user if request and hasattr(request, 'user') and request.user.is_authenticated else None

        # 根据用户名(或ID)生成文件夹名
        user_folder = user.username if user else "anonymous"

        # 设置日志文件夹路径
        log_dir = os.path.join(os.path.dirname(__file__), 'user_logs', user_folder)
        os.makedirs(log_dir, exist_ok=True)

        # 设置日志文件名为日期
        log_filename = f'{now().strftime("%Y-%m-%d")}.log'
        record.log_filepath = os.path.join(log_dir, log_filename)

        return True

配置 settings.py 中的日志系统

settings.py 中,我们仍然使用 UserLogFilter,但不需要在每个视图中显式传递 request 对象。这样,在每个视图内部使用日志时,它会自动根据用户信息生成不同的日志文件。

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'user_log_filter': {
            '()': 'myapp.logging.UserLogFilter',
        },
    },
    'handlers': {
        'user_log': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '',  # 文件路径将在过滤器中动态设置
            'filters': ['user_log_filter'],
        },
    },
    'loggers': {
        'django': {
            'handlers': ['user_log'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

2. 视图中的日志记录

在视图或内部函数中,你可以直接使用 logging 模块,而不需要显式传递 request 对象。 UserLogFilter 会自动在内部获取请求,并根据当前用户生成相应的日志文件。

简洁的视图代码示例

import logging
from django.http import HttpResponse

# 获取logger
logger = logging.getLogger('django')

def my_view(request):
    # 在视图内部直接记录日志
    logger.debug('This is a debug message.')

    # 内部函数中也可以直接记录日志
    some_internal_function(request)

    return HttpResponse('Log written for user {}'.format(request.user.username if request.user.is_authenticated else 'anonymous'))

def some_internal_function(request):
    # 内部函数也可以直接使用日志
    logger.info('This is an info message from the internal function.')

3. 结果

  1. 自动生成用户文件夹:日志将根据用户自动存储在不同的文件夹下,每个用户有自己的文件夹,文件夹名字为 user_logs/{username}
  2. 简洁的使用方式:在视图和内部函数中,你不需要显式传递 request 对象,只需使用 logging.getLogger() 获取日志记录器并记录日志。
  3. 自动路径管理:日志文件会自动按日期和用户划分,文件名为 YYYY-MM-DD.log,保存在相应用户的文件夹中。

4. 目录结构

假设有两个用户:alicebob,日志文件会被存储在:

user_logs/
    ├── alice/
    │   └── 2025-01-09.log
    ├── bob/
    │   └── 2025-01-09.log
    └── anonymous/
        └── 2025-01-09.log

5. 总结

  • 简洁性:只需要在视图函数和内部函数中使用 logging,不需要显式传递 request 或配置额外的中间件。
  • 自动化处理:日志文件路径和文件名根据用户和日期自动生成。
  • 集中配置:所有的日志配置和路径管理都集中在 settings.py 中,通过 UserLogFilter 完成,保持简洁且可维护。

这种方式适合你希望在视图和内部函数中记录日志,同时不需要显式传递 request,且自动按用户分类生成日志文件。