50 lines
1.4 KiB
Python
50 lines
1.4 KiB
Python
"""日志审计存储层:全链路操作/注册注销/通信记录。"""
|
|
import time
|
|
|
|
import redis.asyncio as aioredis
|
|
|
|
from app.models.schemas import LogEntry
|
|
|
|
LOG_KEY = "log:audit"
|
|
LOG_MAX = 2000
|
|
|
|
|
|
class LogRepo:
|
|
def __init__(self, redis: aioredis.Redis):
|
|
self.redis = redis
|
|
|
|
async def append(
|
|
self,
|
|
message: str,
|
|
*,
|
|
level: str = "info",
|
|
source: str = "gateway",
|
|
scope: str = "system",
|
|
request_id: str | None = None,
|
|
agent_id: str | None = None,
|
|
) -> None:
|
|
entry = LogEntry(
|
|
level=level,
|
|
source=source,
|
|
scope=scope,
|
|
request_id=request_id,
|
|
agent_id=agent_id,
|
|
message=message,
|
|
)
|
|
await self.redis.lpush(LOG_KEY, entry.model_dump_json())
|
|
await self.redis.ltrim(LOG_KEY, 0, LOG_MAX - 1)
|
|
|
|
async def list(self, limit: int = 200, request_id: str | None = None, agent_id: str | None = None) -> list[LogEntry]:
|
|
raw = await self.redis.lrange(LOG_KEY, 0, limit - 1)
|
|
out = []
|
|
for item in raw:
|
|
try:
|
|
entry = LogEntry.model_validate_json(item)
|
|
except Exception:
|
|
continue
|
|
if request_id and entry.request_id != request_id:
|
|
continue
|
|
if agent_id and entry.agent_id != agent_id:
|
|
continue
|
|
out.append(entry)
|
|
return out |