You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
iTi-System/iti_system/service/sys/sys_log.py

98 lines
2.9 KiB
Python

from __future__ import annotations
from flask import has_request_context, request, current_app
from typing import Optional
import json
from flask_jwt_extended import current_user
from iti_system.models import SysLog
from iti.applications.extensions.db import db
from iti.applications.common.enums import LogType
from iti.applications.common.utils.sys_log_helper import (
summarize_response_json,
safe_json_dumps,
truncate_text,
)
def add_sys_log(
name: str,
*,
type: "LogType | str" = LogType.OPERATION,
desc: Optional[str] = None,
success: Optional[bool] = None,
response: Optional[dict | str] = None,
exception: Optional[Exception | str] = None,
extra: Optional[dict] = None,
) -> None:
"""
手动新增系统日志(请求内/外均可调用)。
- 共用 after_request 的摘要策略与配置项
- 参数尽量少,自动采集请求上下文信息(如有)
"""
max_body_chars = (
int(current_app.config.get("SYSLOG_MAX_BODY_CHARS", 2048))
if current_app
else 2048
)
items_sample_size = (
int(current_app.config.get("SYSLOG_ITEMS_SAMPLE", 5)) if current_app else 5
)
method = path = user_agent = ip = None
headers = query = body = None
user_id = None
if has_request_context():
method = request.method
path = request.path
headers = {k: request.headers.getlist(k) for k in request.headers.keys()}
query = request.args.to_dict()
body = request.get_json(silent=True) or {}
user_id = current_user.id if current_user else None
user_agent = request.headers.get("User-Agent", "None")
ip = request.remote_addr or request.headers.get("X-Forwarded-For")
resp_text: Optional[str] = None
if isinstance(response, dict):
summarized = summarize_response_json(response, items_sample_size)
resp_text = safe_json_dumps(
summarized, ensure_ascii=False, max_chars=max_body_chars
)
elif isinstance(response, str):
resp_text = truncate_text(response, max_body_chars)
if success is None:
success = False if exception else None
log = SysLog(
name=name,
desc=desc or "",
type=(
type.value
if isinstance(type, LogType)
else (type or LogType.OPERATION.value)
),
method=method,
user_id=user_id,
path=path,
ip=ip,
user_agent=user_agent,
headers=json.dumps(headers, ensure_ascii=False)
if headers is not None
else None,
query_params=json.dumps(query, ensure_ascii=False)
if query is not None
else None,
body_params=json.dumps(body, ensure_ascii=False) if body is not None else None,
execution_time=None,
response=resp_text,
success=success,
exception=str(exception) if exception else None,
)
db.session.add(log)
db.session.commit()