modify: mqtt心跳转发
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
"""
|
||||
AI Box Sophon Adapter — 告警记录清理
|
||||
|
||||
当告警记录超过配置的 max_records 时,自动清理最早的记录及其关联的视频文件。
|
||||
"""
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from sqlalchemy import select, func, asc
|
||||
|
||||
from .models.orm import AlarmRecord
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def trim_alarm_records(db_session, upload_root: str, max_records: int) -> int:
|
||||
"""
|
||||
裁剪告警记录,保留最新的 max_records 条
|
||||
|
||||
删除超出限制的最早记录,同时清理关联的视频文件目录。
|
||||
|
||||
Args:
|
||||
db_session: SQLAlchemy 异步 session
|
||||
upload_root: 上传文件根目录(如 ./data/uploads)
|
||||
max_records: 最大保留条数,<= 0 表示不限制
|
||||
|
||||
Returns:
|
||||
实际删除的记录数
|
||||
"""
|
||||
if max_records <= 0:
|
||||
return 0
|
||||
|
||||
# 查询当前总记录数
|
||||
count_result = await db_session.execute(
|
||||
select(func.count()).select_from(AlarmRecord)
|
||||
)
|
||||
total = count_result.scalar() or 0
|
||||
|
||||
if total <= max_records:
|
||||
return 0
|
||||
|
||||
# 超出数量
|
||||
overflow = total - max_records
|
||||
|
||||
# 查询最早的 overflow 条记录(按 created_at 升序)
|
||||
stmt = (
|
||||
select(AlarmRecord)
|
||||
.order_by(asc(AlarmRecord.created_at)) # type: ignore
|
||||
.limit(overflow)
|
||||
)
|
||||
result = await db_session.execute(stmt)
|
||||
old_records = result.scalars().all()
|
||||
|
||||
deleted_count = 0
|
||||
for record in old_records:
|
||||
# 清理关联的视频文件目录
|
||||
if record.video_file:
|
||||
_delete_video_dir(upload_root, record.video_file)
|
||||
|
||||
await db_session.delete(record)
|
||||
deleted_count += 1
|
||||
|
||||
await db_session.commit()
|
||||
|
||||
if deleted_count > 0:
|
||||
logger.info(
|
||||
f"[AlarmTrim] 已清理 {deleted_count} 条告警记录 "
|
||||
f"(保留最新 {max_records} 条,原共 {total} 条)"
|
||||
)
|
||||
|
||||
return deleted_count
|
||||
|
||||
|
||||
def _delete_video_dir(upload_root: str, video_id: str) -> None:
|
||||
"""
|
||||
删除告警关联的视频文件目录
|
||||
|
||||
视频存储路径: {upload_root}/aibox_sophon_adapter/{video_id}/
|
||||
|
||||
Args:
|
||||
upload_root: 上传根目录
|
||||
video_id: 视频唯一标识(VideoId)
|
||||
"""
|
||||
video_dir = os.path.join(upload_root, "aibox_sophon_adapter", video_id)
|
||||
|
||||
if not os.path.isdir(video_dir):
|
||||
return
|
||||
|
||||
try:
|
||||
shutil.rmtree(video_dir)
|
||||
logger.debug(f"[AlarmTrim] 已删除视频目录: {video_dir}")
|
||||
except OSError as e:
|
||||
logger.warning(f"[AlarmTrim] 删除视频目录失败 [{video_dir}]: {e}")
|
||||
Reference in New Issue
Block a user