| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- from django.utils import timezone
- from .models import OperationLog
- class OperationLogger:
- @staticmethod
- def log_operation(request, operation_content, operation_level, operator=None,
- operation_result='success', module_name=None, object_id=None):
- """
- 记录操作日志
-
- Args:
- request: HttpRequest对象
- operation_content: 操作内容描述
- operation_level: 操作级别
- operator: 操作者标识(用户名等),如果为None则尝试从request中获取
- operation_result: 操作结果,'success'或'failure'
- module_name: 模块名称,用于分类
- object_id: 操作对象ID
- """
- try:
- # 验证必需参数
- if not request or not operation_content or not operation_level:
- raise ValueError("缺少必需的参数: request, operation_content, operation_level")
-
- # 获取操作者标识
- operator_identifier = OperationLogger._get_operator_identifier(request, operator)
-
- # 获取模块名称(如果没有提供则从请求路径推断)
- if not module_name:
- module_name = OperationLogger._infer_module_name(request.path)
-
- # 获取客户端信息
- ip_address = OperationLogger._get_client_ip(request)
- user_agent = request.META.get('HTTP_USER_AGENT', '')[:500] # 限制长度
-
- # 创建日志记录
- OperationLog.objects.create(
- operator=operator_identifier,
- operation_content=operation_content,
- operation_level=operation_level,
- operation_result=operation_result,
- ip_address=ip_address,
- user_agent=user_agent,
- request_method=request.method,
- request_path=request.path,
- module_name=module_name,
- object_id=object_id
- )
-
- except Exception as e:
- # 日志记录失败不应影响主要业务逻辑,但需要记录错误
- import logging
- logger = logging.getLogger(__name__)
- logger.error(f"操作日志记录失败: {str(e)}", exc_info=True)
-
- @staticmethod
- def _get_operator_identifier(request, operator):
- """获取操作者标识"""
- # 如果提供了operator参数,直接使用
- if operator is not None:
- return str(operator)
-
- # 尝试从request中获取用户信息
- if hasattr(request, 'user') and request.user.is_authenticated:
- # 优先使用username,如果没有则使用其他标识
- if hasattr(request.user, 'username'):
- return request.user.username
- elif hasattr(request.user, 'get_username'):
- return request.user.get_username()
- else:
- return f"用户ID:{request.user.id}" if hasattr(request.user, 'id') else "认证用户"
-
- # 如果都没有,返回未知用户
- return "未知用户"
-
- @staticmethod
- def _infer_module_name(path):
- """从路径推断模块名称"""
- if not path:
- return 'unknown'
-
- # 移除首尾斜杠并分割路径
- path_parts = path.strip('/').split('/')
- if path_parts:
- # 使用第一个非空路径部分作为模块名
- for part in path_parts:
- if part and part not in ('api', 'v1', 'v2'): # 跳过常见的API前缀
- return part
- return 'unknown'
-
- @staticmethod
- def _get_client_ip(request):
- """获取客户端IP地址"""
- x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
- if x_forwarded_for:
- ip = x_forwarded_for.split(',')[0].strip()
- else:
- ip = request.META.get('REMOTE_ADDR')
- return ip
- # 快捷函数
- def log_operation(request, operation_content, operation_level, operator=None,
- operation_result='success', module_name=None, object_id=None):
- """快捷记录操作日志函数"""
- OperationLogger.log_operation(
- request=request,
- operation_content=operation_content,
- operation_level=operation_level,
- operator=operator,
- operation_result=operation_result,
- module_name=module_name,
- object_id=object_id
- )
- # 专门用于成功操作的快捷函数
- def log_success_operation(request, operation_content, operation_level, operator=None,
- module_name=None, object_id=None):
- """记录成功操作的快捷函数"""
- log_operation(
- request=request,
- operation_content=operation_content,
- operation_level=operation_level,
- operator=operator,
- operation_result='success',
- module_name=module_name,
- object_id=object_id
- )
- # 专门用于失败操作的快捷函数
- def log_failure_operation(request, operation_content, operation_level, operator=None,
- module_name=None, object_id=None):
- """记录失败操作的快捷函数"""
- log_operation(
- request=request,
- operation_content=operation_content,
- operation_level=operation_level,
- operator=operator,
- operation_result='failure',
- module_name=module_name,
- object_id=object_id
- )
|