fix: Windows syslog兼容 + API设计文档

This commit is contained in:
xiaji
2026-06-07 18:09:35 +08:00
parent 22e3e09b24
commit 0e318b1c36
2 changed files with 113 additions and 28 deletions

View File

@@ -198,79 +198,91 @@ FILE_UPLOAD_MAX_MEMORY_SIZE = 524288000
CELERY_BROKER_URL = 'redis://:xjjq1234!@localhost:6379/0' CELERY_BROKER_URL = 'redis://:xjjq1234!@localhost:6379/0'
CELERY_RESULT_BACKEND = 'redis://:xjjq1234!@localhost:6379/0' CELERY_RESULT_BACKEND = 'redis://:xjjq1234!@localhost:6379/0'
import sys
_is_linux = sys.platform == 'linux'
_syslog_handler = {
'level': 'WARNING',
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log',
'facility': 'local0',
'formatter': 'syslog',
} if _is_linux else {
'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler',
'filename': str(LOG_DIR / 'syslog.log'),
'maxBytes': 1024 * 1024 * 50,
'backupCount': 5,
'formatter': 'standard',
'encoding': 'utf-8',
}
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': False, # 不关闭已存在的日志器 'disable_existing_loggers': False,
'formatters': { 'formatters': {
'standard': { # 统一的标准日志格式 'standard': {
'format': '[%(asctime)s] [%(levelname)s] [%(process)d] [%(module)s] %(message)s', 'format': '[%(asctime)s] [%(levelname)s] [%(process)d] [%(module)s] %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S' 'datefmt': '%Y-%m-%d %H:%M:%S'
}, },
'syslog': { # syslog格式用于fail2ban检测 'syslog': {
'format': '%(name)s: %(levelname)s %(message)s' 'format': '%(name)s: %(levelname)s %(message)s'
}, },
}, },
'handlers': { 'handlers': {
'file': { # 日志写入文件的处理器 'file': {
'level': 'INFO', # 日志级别INFO及以上都记录ERROR/WARNING/INFO 'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler', # 日志轮转,防止文件过大 'class': 'logging.handlers.RotatingFileHandler',
# ✅ 核心pathlib对象转字符串logging只接收字符串路径必转
'filename': str(LOG_DIR / 'all_in_one.log'), 'filename': str(LOG_DIR / 'all_in_one.log'),
'maxBytes': 1024 * 1024 * 100, # 单个日志文件最大100MB 'maxBytes': 1024 * 1024 * 100,
'backupCount': 10, # 最多保留10个日志备份 'backupCount': 10,
'formatter': 'standard', # 使用上面定义的统一格式 'formatter': 'standard',
'encoding': 'utf-8', # 编码,防止中文乱码 'encoding': 'utf-8',
}, },
'console': { # 兼容控制台输出(开发调试用,不影响生产) 'console': {
'level': 'INFO', 'level': 'INFO',
'class': 'logging.StreamHandler', 'class': 'logging.StreamHandler',
'formatter': 'standard' 'formatter': 'standard'
}, },
'syslog': { # syslog处理器用于fail2ban检测登录失败 'syslog': _syslog_handler,
'level': 'WARNING', 'auth_file': {
'class': 'logging.handlers.SysLogHandler',
'address': '/dev/log', # Linux系统日志socket
'facility': 'local0',
'formatter': 'syslog',
},
'auth_file': { # 认证日志文件处理器(备选方案)
'level': 'WARNING', 'level': 'WARNING',
'class': 'logging.handlers.RotatingFileHandler', 'class': 'logging.handlers.RotatingFileHandler',
'filename': str(LOG_DIR / 'auth.log'), 'filename': str(LOG_DIR / 'auth.log'),
'maxBytes': 1024 * 1024 * 50, # 50MB 'maxBytes': 1024 * 1024 * 50,
'backupCount': 5, 'backupCount': 5,
'formatter': 'standard', 'formatter': 'standard',
'encoding': 'utf-8', 'encoding': 'utf-8',
}, },
}, },
# 所有日志器配置和原配置完全一致,无需任何修改
'loggers': { 'loggers': {
'django': { # Django核心日志 'django': {
'handlers': ['file'], 'handlers': ['file'],
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,
}, },
'django.request': { # Django的请求日志 'django.request': {
'handlers': ['file'], 'handlers': ['file'],
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,
}, },
'django.security.login': { # 登录安全日志用于fail2ban 'django.security.login': {
'handlers': ['syslog', 'auth_file'], 'handlers': ['syslog', 'auth_file'],
'level': 'WARNING', 'level': 'WARNING',
'propagate': False, 'propagate': False,
}, },
'celery': { # Celery客户端日志Django中提交任务的日志 'celery': {
'handlers': ['file'], 'handlers': ['file'],
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,
}, },
'utils.tasks': { # Celery邮件任务模块 'utils.tasks': {
'handlers': ['file'], 'handlers': ['file'],
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,
}, },
'utils.email_utils': { # 邮件配置模块 'utils.email_utils': {
'handlers': ['file'], 'handlers': ['file'],
'level': 'INFO', 'level': 'INFO',
'propagate': True, 'propagate': True,

View File

@@ -0,0 +1,73 @@
# API Token 鉴权与数据写入接口设计
## 概述
为家庭日报系统增加 Token 鉴权机制,并通过 API 支持外部写入阅读记录、感悟记录、今日计划。
## Token 鉴权
- Token 存储在 `settings.py``API_TOKEN` 配置项中
- 请求需携带 `Authorization: Bearer <token>`
- 新建 `@require_api_token` 装饰器统一校验,校验失败返回 401
- 已有 API`api_submit_summary``api_temp_upload`)同步加上鉴权(破坏性变更,需评估影响)
## 新增 API 端点
所有端点均为 POST支持 `application/json``multipart/form-data`(文件上传场景)。统一返回格式:
```json
{"success": true/false, "message": "...", "id": ...}
```
### 1. POST /api/v1/insight/submit/ - 写入感悟记录
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| content | string | 是 | 感悟内容 |
| speaker | string | 是 | 发言人姓名,匹配 FamilyMember.name |
| date | string | 否 | 日期 YYYY-MM-DD默认今天 |
| file | file | 否 | 附件 |
### 2. POST /api/v1/reading/submit/ - 写入阅读记录
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| type | string | 是 | 阅读类型,匹配 ReadingType.name |
| title | string | 是 | 标题 |
| source | string | 否 | 来源 |
| progress | string | 否 | 进度 |
| note | string | 否 | 阅读笔记 |
| date | string | 否 | 日期 YYYY-MM-DD默认今天 |
| file | file | 否 | 附件 |
### 3. POST /api/v1/plan/submit/ - 写入今日计划
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| content | string | 是 | 计划内容 |
| speaker | string | 否 | 发言人,默认"机器人" |
| priority | string | 否 | 优先级,匹配 Priority.name默认"中" |
| type | string | 否 | 类型,匹配 PlanType.name默认"其他" |
| status | string | 否 | 状态,匹配 Status.name默认"未开始" |
| date | string | 否 | 日期 YYYY-MM-DD默认今天 |
## 实现范围
- `diary_family/settings.py`:新增 `API_TOKEN` 配置
- `core/views.py`:新增 `require_api_token` 装饰器、3 个 API 视图函数
- `core/urls.py`:新增 3 条路由
- 不引入 DRF沿用项目现有 JsonResponse + 函数视图模式
- 不涉及数据库迁移
## 错误处理
- 401Token 缺失或错误
- 400必填字段缺失、外键匹配失败
- 405非 POST 请求
- 500服务器内部错误
- 所有错误统一返回 `{"success": false, "message": "错误描述"}`
## 向后兼容
- 已有 Web 页面功能不受影响
- 已有 API 端点加上 Token 鉴权(需同步更新调用方)