142 lines
6.0 KiB
Python
142 lines
6.0 KiB
Python
from django.db import models
|
|
from django.conf import settings
|
|
|
|
|
|
class ApiRequestLog(models.Model):
|
|
timestamp = models.DateTimeField('请求时间', auto_now_add=True, db_index=True)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.SET_NULL,
|
|
null=True, blank=True,
|
|
related_name='api_request_logs',
|
|
verbose_name='用户'
|
|
)
|
|
username = models.CharField('用户名', max_length=150, default='', blank=True)
|
|
ip_address = models.GenericIPAddressField('IP地址', null=True, blank=True, db_index=True)
|
|
user_agent = models.CharField('User-Agent', max_length=500, default='', blank=True)
|
|
method = models.CharField('HTTP方法', max_length=10, db_index=True)
|
|
path = models.CharField('请求路径', max_length=255, db_index=True)
|
|
query_string = models.TextField('查询参数', default='', blank=True)
|
|
request_body = models.TextField('请求体', default='', blank=True)
|
|
status_code = models.IntegerField('状态码', db_index=True)
|
|
response_size = models.IntegerField('响应大小(字节)', default=0)
|
|
duration_ms = models.FloatField('耗时(毫秒)', db_index=True)
|
|
app_name = models.CharField('应用模块', max_length=50, default='', blank=True, db_index=True)
|
|
is_error = models.BooleanField('是否错误', default=False, db_index=True)
|
|
|
|
class Meta:
|
|
verbose_name = 'API请求日志'
|
|
verbose_name_plural = 'API请求日志'
|
|
ordering = ['-timestamp']
|
|
indexes = [
|
|
models.Index(fields=['timestamp', '-duration_ms'], name='idx_request_time_duration'),
|
|
models.Index(fields=['status_code', 'timestamp'], name='idx_request_status_time'),
|
|
]
|
|
|
|
def __str__(self):
|
|
return f'{self.method} {self.path} - {self.status_code} ({self.duration_ms:.1f}ms)'
|
|
|
|
|
|
class ErrorLog(models.Model):
|
|
LEVEL_CHOICES = [
|
|
('DEBUG', 'DEBUG'),
|
|
('INFO', 'INFO'),
|
|
('WARNING', 'WARNING'),
|
|
('ERROR', 'ERROR'),
|
|
('CRITICAL', 'CRITICAL'),
|
|
]
|
|
|
|
timestamp = models.DateTimeField('发生时间', auto_now_add=True, db_index=True)
|
|
level = models.CharField('日志级别', max_length=20, choices=LEVEL_CHOICES, default='ERROR', db_index=True)
|
|
message = models.TextField('日志消息')
|
|
module = models.CharField('发生模块', max_length=100, default='', blank=True, db_index=True)
|
|
function = models.CharField('发生函数', max_length=100, default='', blank=True)
|
|
line_number = models.IntegerField('行号', null=True, blank=True)
|
|
exception_type = models.CharField('异常类型', max_length=200, default='', blank=True)
|
|
traceback = models.TextField('堆栈信息', default='', blank=True)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.SET_NULL,
|
|
null=True, blank=True,
|
|
related_name='error_logs',
|
|
verbose_name='用户'
|
|
)
|
|
ip_address = models.GenericIPAddressField('IP地址', null=True, blank=True)
|
|
path = models.CharField('请求路径', max_length=255, default='', blank=True)
|
|
request_data = models.TextField('请求数据', default='', blank=True)
|
|
is_resolved = models.BooleanField('是否已处理', default=False, db_index=True)
|
|
resolved_at = models.DateTimeField('处理时间', null=True, blank=True)
|
|
hash_key = models.CharField('错误Hash', max_length=64, unique=True, db_index=True)
|
|
occurrence_count = models.IntegerField('出现次数', default=1)
|
|
|
|
class Meta:
|
|
verbose_name = '错误日志'
|
|
verbose_name_plural = '错误日志'
|
|
ordering = ['-timestamp']
|
|
|
|
def __str__(self):
|
|
return f'[{self.level}] {self.exception_type}: {self.message[:50]}'
|
|
|
|
|
|
class SystemEventLog(models.Model):
|
|
EVENT_TYPE_CHOICES = [
|
|
('login', '用户登录'),
|
|
('logout', '用户登出'),
|
|
('register', '用户注册'),
|
|
('password_reset', '密码重置'),
|
|
('password_change', '密码修改'),
|
|
('profile_update', '资料更新'),
|
|
('phone_bind', '手机绑定'),
|
|
('email_bind', '邮箱绑定'),
|
|
('avatar_upload', '头像上传'),
|
|
('checkin', '每日签到'),
|
|
('points_change', '积分变动'),
|
|
('coins_change', 'y币变动'),
|
|
('article_create', '文章创建'),
|
|
('article_update', '文章更新'),
|
|
('article_delete', '文章删除'),
|
|
('comment_create', '评论创建'),
|
|
('favorite_add', '收藏添加'),
|
|
('favorite_remove', '收藏取消'),
|
|
('blacklist_add', '拉黑用户'),
|
|
('blacklist_remove', '取消拉黑'),
|
|
('admin_action', '管理员操作'),
|
|
('system_error', '系统错误'),
|
|
('other', '其他'),
|
|
]
|
|
|
|
RESULT_CHOICES = [
|
|
('success', '成功'),
|
|
('failed', '失败'),
|
|
('partial', '部分成功'),
|
|
]
|
|
|
|
timestamp = models.DateTimeField('事件时间', auto_now_add=True, db_index=True)
|
|
event_type = models.CharField('事件类型', max_length=50, choices=EVENT_TYPE_CHOICES, db_index=True)
|
|
user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.CASCADE,
|
|
related_name='system_event_logs',
|
|
verbose_name='操作用户'
|
|
)
|
|
target_user = models.ForeignKey(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.SET_NULL,
|
|
null=True, blank=True,
|
|
related_name='targeted_event_logs',
|
|
verbose_name='目标用户'
|
|
)
|
|
description = models.CharField('描述', max_length=500, default='', blank=True)
|
|
metadata = models.JSONField('额外数据', default=dict, blank=True)
|
|
ip_address = models.GenericIPAddressField('IP地址', null=True, blank=True)
|
|
user_agent = models.CharField('User-Agent', max_length=500, default='', blank=True)
|
|
result = models.CharField('结果', max_length=20, choices=RESULT_CHOICES, default='success', db_index=True)
|
|
|
|
class Meta:
|
|
verbose_name = '系统事件日志'
|
|
verbose_name_plural = '系统事件日志'
|
|
ordering = ['-timestamp']
|
|
|
|
def __str__(self):
|
|
return f'{self.get_event_type_display()} - {self.user.username} ({self.get_result_display()})'
|