Files
aiagent/backend/app/core/logging_config.py
renjianbo beff3fac8d fix: delete agent 500 error + dynamic personality + deployment guide
- Fix delete agent 500: clean up FK records (agent_llm_logs, permissions,
  schedules, executions, team_members) and unbind goals/tasks before delete
- Remove hardcoded personality templates in Android, replace with dynamic
  system prompt generation from name + description
- Set promptSectionsEnabled=false to bypass PromptComposer for personality
- Add Tencent Cloud Linux deployment guide (Docker Compose)
- Accumulated backend service updates, frontend UI fixes, Android app changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-06-29 01:17:21 +08:00

77 lines
2.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
JSON 结构化日志配置 — 用于 ELK 日志聚合。
用法: 在 main.py 启动时调用 setup_json_logging() 即可。
会在 logs/ 目录下并行输出 app.json.logJSON 格式)。
现有文本格式日志不受影响。
"""
from __future__ import annotations
import json
import logging
import os
from datetime import datetime, timezone
from logging.handlers import RotatingFileHandler
from pathlib import Path
from typing import Any
from app.core.config import settings
class JsonFormatter(logging.Formatter):
"""将日志记录格式化为单行 JSON便于 Filebeat → Elasticsearch 采集。"""
def format(self, record: logging.LogRecord) -> str:
log_entry: dict[str, Any] = {
"timestamp": datetime.fromtimestamp(
record.created, tz=timezone.utc
).isoformat(),
"level": record.levelname,
"logger": record.name,
"message": record.getMessage(),
"module": record.module,
"function": record.funcName,
"line": record.lineno,
}
# 异常信息
if record.exc_info and record.exc_info[1]:
log_entry["exception"] = self.formatException(record.exc_info)
# 上下文字段(如 request_id / user_id
for key in ("request_id", "user_id", "workspace_id", "client_ip", "method", "path", "status_code", "duration_ms"):
val = getattr(record, key, None)
if val is not None:
log_entry[key] = val
return json.dumps(log_entry, ensure_ascii=False, default=str)
def setup_json_logging() -> None:
"""为 root logger 添加 JSON 格式的 RotatingFileHandler。
日志写入 LOG_DIR/app.json.log大小达到 LOG_MAX_BYTES 时轮转。
"""
log_dir = Path(settings.LOG_DIR)
log_dir.mkdir(parents=True, exist_ok=True)
json_log_path = log_dir / "app.json.log"
# 避免重复添加uvicorn reload 时会重新执行 startup
root = logging.getLogger()
for h in root.handlers:
if isinstance(h, RotatingFileHandler) and str(json_log_path) in getattr(h, 'baseFilename', ''):
return
handler = RotatingFileHandler(
json_log_path,
maxBytes=settings.LOG_MAX_BYTES,
backupCount=settings.LOG_BACKUP_COUNT,
encoding="utf-8",
)
handler.setFormatter(JsonFormatter())
handler.setLevel(getattr(logging, settings.LOG_LEVEL.upper(), logging.INFO))
root.addHandler(handler)
logging.getLogger(__name__).info("JSON 日志已启用 → %s", json_log_path)