# -*- coding: utf-8 -*- """后台审计日志。 (自 auth_system.py 拆出,行为与原实现一致;DB 访问已迁移为原生异步。) """ import time from .db import ( _q, _x, write_transaction, ) # ============ 日志 ============ # 日志裁剪计数器(原实现用 secrets.randbelow 触发——密码学随机数浪费熵池) _LOG_WRITE_COUNTER = {'n': 0} async def add_log(log_type: str, username: str, ip: str, action: str, detail: str = '') -> None: try: await _x('INSERT INTO logs (type, username, ip, action, detail, time) VALUES (?, ?, ?, ?, ?, ?)', (log_type, username or '', ip or '-', action or '', detail or '', time.strftime('%Y-%m-%d %H:%M:%S'))) # 控制日志表体积(每 50 次写入触发一次裁剪) _LOG_WRITE_COUNTER['n'] += 1 if _LOG_WRITE_COUNTER['n'] % 50 == 0: await _x('DELETE FROM logs WHERE id NOT IN (SELECT id FROM logs ORDER BY id DESC LIMIT 5000)') except Exception: pass async def query_logs(log_type: str, limit: int = 100, offset: int = 0): """分页查询日志,返回 (日志列表, 总条数)""" limit = max(1, min(int(limit), 500)) offset = max(0, int(offset)) rows = await _q('SELECT * FROM logs WHERE type = ? ORDER BY id DESC LIMIT ? OFFSET ?', (log_type, limit, offset)) total_row = await _q('SELECT COUNT(*) AS c FROM logs WHERE type = ?', (log_type,)) total = int(total_row[0]['c']) if total_row else 0 return [dict(r) for r in rows], total async def clear_logs(log_type: str) -> int: """清除指定类型的全部日志,返回删除条数""" async with write_transaction() as conn: cur = await conn.execute('DELETE FROM logs WHERE type = ?', (log_type,)) return cur.rowcount