Skip to content

日志管理

youlai-django 提供 API 操作日志记录功能,日志存储在 sys_log 表中。

日志表结构

数据库表sys_log

字段类型说明
idbigint主键
modulevarchar模块标识
contentvarchar日志内容
request_methodvarchar请求方式
request_urivarchar请求路径
request_paramstext请求参数
response_datatext响应内容
ipvarchar客户端 IP
browservarchar浏览器信息
osvarchar操作系统
durationint耗时(毫秒)
create_bybigint操作人
create_timedatetime操作时间

日志接口

分页查询

GET /api/v1/logs/page

参数

参数类型说明
pageNumint页码
pageSizeint每页数量
keywordsstring关键字
createTimestring时间范围(起止时间,逗号分隔)

访问趋势

GET /api/v1/logs/visit-trend

参数

参数类型说明
startDatestring开始日期(yyyy-MM-dd)
endDatestring结束日期(yyyy-MM-dd)

返回

json
{
  "code": "00000",
  "msg": "操作成功",
  "data": {
    "dates": ["2024-01-15", "2024-01-16"],
    "pvList": [1000, 1200],
    "ipList": [500, 600]
  }
}

访问统计

GET /api/v1/logs/visit-stats

返回

json
{
  "code": "00000",
  "data": {
    "todayUv": 500,
    "todayPv": 1000,
    "totalUv": 10000,
    "totalPv": 50000
  }
}

日志记录方式

中间件方式

在 Django 中间件中记录请求日志:

python
# infra/middleware/log_middleware.py
import time
import json
from django.utils.deprecation import MiddlewareMixin

class LogMiddleware(MiddlewareMixin):
    def process_request(self, request):
        request.start_time = time.time()

    def process_response(self, request, response):
        duration = int((time.time() - request.start_time) * 1000)
        
        # 记录日志
        Log.objects.create(
            module='API',
            content=f"{request.method} {request.path}",
            request_method=request.method,
            request_uri=request.path,
            request_params=json.dumps(request.GET.dict()),
            response_data=response.content.decode()[:500],
            ip=self.get_client_ip(request),
            duration=duration,
        )
        
        return response

    def get_client_ip(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            return x_forwarded_for.split(',')[0]
        return request.META.get('REMOTE_ADDR')

装饰器方式

python
from functools import wraps
import time

def log_operation(module='SYSTEM'):
    def decorator(func):
        @wraps(func)
        def wrapper(self, request, *args, **kwargs):
            start_time = time.time()
            
            try:
                response = func(self, request, *args, **kwargs)
                duration = int((time.time() - start_time) * 1000)
                
                # 记录成功日志
                Log.objects.create(
                    module=module,
                    content=f"{request.method} {request.path}",
                    request_method=request.method,
                    request_uri=request.path,
                    duration=duration,
                )
                
                return response
            except Exception as e:
                # 记录失败日志
                Log.objects.create(
                    module=module,
                    content=f"操作失败: {str(e)}",
                    request_method=request.method,
                    request_uri=request.path,
                )
                raise
        
        return wrapper
    return decorator

Django Logging 配置

python
# config/settings/base.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '{levelname} {asctime} {module} {message}',
            'style': '{',
        },
    },
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
        'file': {
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': 'logs/django.log',
            'maxBytes': 10 * 1024 * 1024,  # 10MB
            'backupCount': 10,
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['console'],
            'level': 'INFO',
        },
        'youlai': {
            'handlers': ['console', 'file'],
            'level': 'DEBUG',
        },
    },
}

日志查看

命令行查看

bash
# 查看日志文件
tail -f logs/django.log

# 搜索错误
grep "ERROR" logs/django.log

Django Admin 查看

配置 ModelAdmin 后可在后台查看:

python
# system/logs/admin.py
from django.contrib import admin
from .models import Log

@admin.register(Log)
class LogAdmin(admin.ModelAdmin):
    list_display = ['id', 'module', 'content', 'ip', 'create_time']
    list_filter = ['module', 'request_method']
    search_fields = ['content', 'ip']
    readonly_fields = [f.name for f in Log._meta.fields]

相关文件

文件说明
system/logs/models.py日志模型
system/logs/views.py日志接口
infra/middleware/log_middleware.py日志中间件

参考资料

基于 MIT 许可发布