文档目录
AI使用日志表(dou_ai_usage_log)

简介

本设计文档围绕 DouPHP 的 AI 使用日志表(实际表名为 dou_ai_log,对应业务上的“AI使用统计”)进行系统化说明。文档覆盖字段设计、写入流程、查询能力、成本计算、性能监控、错误追踪、大数据量存储优化、查询调优以及数据归档策略,面向 AI 运维人员提供完整的监控分析与成本控制指南。

项目结构

与 dou_ai_usage_log(即 dou_ai_log)相关的关键位置如下:

  • 数据库定义:模块 SQL 中定义了 dou_ai_log 及关联表(应用、密钥、模型、供应商、异步任务等)。
  • 数据模型:Admin 层 AiLog 模型封装了可写字段、类型转换、筛选器与名称解析方法。
  • 写入服务:UsageRecorder 负责将一次 AI 调用结果落库为日志,并维护密钥失败计数与内容清理。
  • 查询服务:AiLogService 提供分页列表、详情查看、删除与批量操作。
  • 控制器:AiLogController 暴露后台路由,驱动服务层完成展示与操作。
  • 视图:ai_log.htm 用于展示日志详情与基础信息。
graph TB
A["AI 调用方<br/>生成/翻译/图像等"] --> B["UsageRecorder<br/>记录用量与元数据"]
B --> C["AiLog 模型<br/>写入 dou_ai_log"]
B --> D["AiGateway<br/>更新密钥状态/失败计数"]
E["AiLogService<br/>分页/筛选/详情"] --> F["AiLog 模型<br/>读取与聚合"]
G["AiLogController<br/>后台路由"] --> E
H["ai_log.htm<br/>管理界面"] --> G

核心组件

  • 数据表 dou_ai_log:承载每次 AI 请求的使用明细,包括管理员、应用、模型、供应商、密钥、请求ID、tokens、耗时、HTTP状态码、错误标志与信息、最终提示词、响应内容、API端点、IP、元数据与时间戳。
  • 模型 AiLog:定义可写字段、类型转换、常用筛选器(按管理员、供应商、模型、错误标志、时间范围)、默认排序与名称解析辅助方法。
  • 写入服务 UsageRecorder:统一落库入口,负责 tokens/耗时/状态码/错误信息/端点/IP/元数据的提取与裁剪,维护密钥失败计数,定期清理历史大字段。
  • 查询服务 AiLogService:提供后台列表页数据组装、详情渲染、删除与批量删除,支持多维度筛选与分页。
  • 控制器 AiLogController:对外暴露后台路由,协调服务层完成展示与操作。
  • 视图 ai_log.htm:展示日志基础信息、token 用量、请求信息与元数据等。

架构总览

下图展示了从 AI 调用到日志落库、再到后台查看的完整链路,以及与密钥、模型、供应商等实体的关系。

sequenceDiagram
participant U as "管理员/业务"
participant R as "UsageRecorder"
participant M as "AiLog 模型"
participant G as "AiGateway"
participant S as "AiLogService"
participant V as "ai_log.htm"
U->>R : 提交一次AI调用结果(含usage/config/error等)
R->>M : 创建日志行(admin_id/app_id/model_id/provider_id/key_id/request_id/tokens/duration/status_code/has_error/error_message/prompt_content/response_content/endpoint/ip/metadata/created_at)
R->>G : 更新密钥last_used/failure_count
Note over R,M : 自动裁剪prompt/response大小并定时清理过期内容
U->>S : 访问后台日志列表/详情
S->>M : 按条件筛选+分页
S-->>V : 返回渲染数据
V-->>U : 展示日志详情

详细组件分析

数据表设计与字段语义

  • 主键与索引
    • 主键:id(自增 bigint)
    • 索引:admin_id、app_id、created_at(便于按管理员、应用、时间范围检索)
  • 核心字段
    • admin_id:发起请求的管理员ID
    • app_id:所属AI应用ID(可为空)
    • model_id:使用的模型ID
    • provider_id:供应商ID
    • key_id:本次使用的密钥ID(可为空)
    • request_id:唯一请求ID(用于去重与追踪)
    • prompt_tokens/completion_tokens/total_tokens:输入/输出/总tokens
    • duration:请求耗时(毫秒)
    • status_code:HTTP状态码
    • has_error:是否错误(0/1)
    • error_message:错误信息(文本)
    • prompt_content:最终完整提示词(文本,受大小限制)
    • response_content:AI最终返回内容(长文本,受大小限制)
    • endpoint:API端点地址
    • ip:管理员IP
    • metadata:扩展元数据(JSON)
    • created_at:记录时间
  • 关联实体
    • 应用:dou_ai(name)
    • 密钥:dou_ai_key(alias)
    • 模型:dou_ai_model(name, model_code)
    • 供应商:dou_ai_provider(name, code)
    • 异步任务:dou_ai_task(用于图像/视频等异步场景补记)

写入流程与统计口径

  • 同步调用记录
    • 从调用结果中提取 usage 与 config,写入 tokens、duration、status_code、has_error、error_message、endpoint、ip、metadata 等。
    • 对 prompt_content 与 response_content 做长度裁剪,避免单行过大。
    • 更新密钥 last_used 与 failure_count(成功归零,失败累加)。
  • 异步任务补记
    • 当异步任务达到 succeeded 终态时,基于 task 信息补记一条日志,tokens 记为 0(图像/视频按张/秒计费),原始 usage 存入 metadata。
    • 通过 request_id 去重,确保只记录一次。
  • 内容清理
    • 定期清理超过保留期的 prompt_content 与 response_content,释放空间。
flowchart TD
Start(["开始"]) --> Extract["提取usage/config/success/error"]
Extract --> BuildRow["构建日志行<br/>tokens/duration/status/endpoint/ip/metadata"]
BuildRow --> LimitContent["裁剪prompt/response大小"]
LimitContent --> WriteDB["写入dou_ai_log"]
WriteDB --> UpdateKey{"是否有关键ID?"}
UpdateKey --> |是| TouchKey["更新last_used"]
UpdateKey --> |否| Done(["结束"])
TouchKey --> SuccessCheck{"是否成功?"}
SuccessCheck --> |是| ResetFail["重置失败计数"]
SuccessCheck --> |否| BumpFail["增加失败计数"]
ResetFail --> Done
BumpFail --> Done

查询与展示能力

  • 列表筛选
    • 支持按管理员、供应商、模型、错误标志、时间范围筛选,默认按 id 倒序。
    • 分页加载,提升大数据量下的列表性能。
  • 详情展示
    • 展示管理员名、供应商名、模型名、应用名、密钥别名、错误标志、状态码、tokens、耗时、请求ID、端点、IP、元数据、最终提示词与响应内容(JSON美化或原样)。
  • 删除与批量操作
    • 支持单条删除与批量删除,并记录审计日志。
sequenceDiagram
participant C as "AiLogController"
participant S as "AiLogService"
participant M as "AiLog 模型"
participant V as "ai_log.htm"
C->>S : getAdminIndexPageData(req)
S->>M : filterBy... + paginate()
M-->>S : 列表+分页
S-->>C : 组装后的列表数据
C-->>V : 渲染列表页
C->>S : getViewBundle(id)
S->>M : findAdminRow(id)
M-->>S : 单条记录
S-->>C : 详情数据名称/格式化内容
C-->>V : 渲染详情页

成本计算与性能监控

  • 成本计算
    • 以 tokens 为核心计量单位:prompt_tokens、completion_tokens、total_tokens。
    • 对于图像/视频等异步任务,当前 token 计为 0,原始 usage 保存在 metadata 中,便于后续接入单价模型后回填成本。
  • 性能监控
    • duration 记录单次请求耗时(毫秒),可用于 P95/P99 延迟分析。
    • status_code 与 has_error 用于成功率与错误率统计。
    • endpoint 用于定位具体 API 端点异常。
  • 错误追踪
    • error_message 记录错误信息;metadata 可扩展记录上下文(如 placement、module、count 等)。
    • 密钥失败计数用于熔断与告警。

数据模型类图

classDiagram
class AiLog {
+int id
+int admin_id
+int app_id
+int model_id
+int provider_id
+int key_id
+string request_id
+int prompt_tokens
+int completion_tokens
+int total_tokens
+int duration
+int status_code
+int has_error
+text error_message
+text prompt_content
+longtext response_content
+string endpoint
+string ip
+text metadata
+datetime created_at
+scopeFilterByAdminId(query, adminId)
+scopeFilterByProviderId(query, providerId)
+scopeFilterByModelId(query, modelId)
+scopeFilterByHasError(query, hasErrorRaw)
+scopeFilterByCreatedAtStart(query, timeStart)
+scopeFilterByCreatedAtEnd(query, timeEnd)
+scopeApplyDefaultOrder(query)
+static findAdminRow(id)
+static getProviderName(providerId)
+static getModelName(modelId)
+static getApplicationName(appId)
+static getAdminName(adminId)
}
class UsageRecorder {
+record(result, appId, adminId, ip, metadata, prompt)
+recordAsyncTaskSuccess(task, ip)
-limitContent(content)
-purgeExpiredContent()
}
class AiLogService {
+getAdminIndexPageData(req)
+getViewBundle(id)
+delete(id, post)
+action(post)
}
UsageRecorder --> AiLog : "写入"
AiLogService --> AiLog : "读取/筛选"

依赖关系分析

  • 写入侧依赖
    • UsageRecorder 依赖 AiLog 模型进行落库,并依赖 AiGateway 更新密钥状态与失败计数。
    • 异步任务补记依赖 ai_task 表获取任务上下文,并通过 request_id 去重。
  • 查询侧依赖
    • AiLogService 依赖 AiLog 模型的筛选器与分页能力,并在详情中关联查询应用、模型、供应商、密钥等信息。
  • 视图依赖
    • ai_log.htm 依赖服务层返回的数据进行展示,包括格式化后的 JSON 与语言化文案。
graph LR
UR["UsageRecorder"] --> ALM["AiLog 模型"]
UR --> AG["AiGateway"]
UR --> AT["ai_task 表"]
ALS["AiLogService"] --> ALM
ALM --> AP["ai 表"]
ALM --> AK["ai_key 表"]
ALM --> AM["ai_model 表"]
ALM --> AV["ai_provider 表"]
AC["AiLogController"] --> ALS
V["ai_log.htm"] --> AC

性能与存储优化

  • 索引与查询
    • 已有索引:admin_id、app_id、created_at。建议在高并发场景下,结合常见查询组合添加复合索引,例如 (admin_id, created_at)、(provider_id, created_at)、(model_id, created_at)。
    • 列表页已分页,避免全表扫描;详情查询通过主键或唯一键,性能稳定。
  • 大字段控制
    • prompt_content 与 response_content 在写入时进行长度裁剪,防止单行过大影响 IO。
    • 定期清理超过保留期的大字段,释放存储空间。
  • 写入吞吐
    • 建议在高峰期采用批处理写入或消息队列缓冲,降低数据库压力。
    • 对高频写入路径(UsageRecorder::record)进行性能测试与压测,必要时拆分写入逻辑。
  • 归档策略
    • 按时间维度归档历史日志(如按月分表或迁移至冷存储),保留热数据在在线库。
    • 归档前可先剥离大字段,仅保留统计字段与元数据摘要。
  • 监控与告警
    • 基于 duration、status_code、has_error 建立监控指标,设置阈值告警(如错误率突增、P99延迟升高)。
    • 结合密钥失败计数,实现熔断与降级策略。

故障排查指南

  • 常见问题定位
    • 错误信息:查看 error_message 与 has_error,快速识别失败原因。
    • 端点与状态码:通过 endpoint 与 status_code 定位上游接口问题。
    • 密钥健康:检查密钥 last_used 与 failure_count,判断是否触发熔断。
    • 异步任务:若 tokens 为 0 但存在结果,检查 metadata 中的 task_id 与 usage 原始数据。
  • 数据一致性
    • 使用 request_id 进行去重校验,避免重复记录。
    • 异步任务补记通过事务与锁保证幂等性。
  • 性能问题
    • 列表慢:检查筛选条件是否命中索引,必要时添加复合索引。
    • 详情慢:确认是否存在 N+1 查询,可在服务层预取关联数据。
  • 容量问题
    • 关注 prompt_content 与 response_content 的大小与保留策略,及时清理历史大字段。
    • 制定归档计划,避免在线库膨胀。

结论

dou_ai_log 作为 AI 使用统计的核心表,提供了完整的请求级观测能力,涵盖管理员、应用、模型、供应商、密钥、tokens、耗时、状态码、错误信息、端点、IP、元数据等关键字段。配合 UsageRecorder 的写入规范与 AiLogService 的查询能力,可实现成本核算、性能监控与错误追踪。通过合理的索引设计、大字段裁剪、归档策略与监控告警,可在大数据量场景下保持稳定的查询与写入性能,为 AI 运维提供可靠的支撑。

附录

  • 关键视图与展示
    • 列表页:支持多维度筛选与分页。
    • 详情页:展示基础信息、token 用量、请求信息与元数据,JSON 美化显示。
  • 关联表参考
    • 应用表(dou_ai):应用名称、形态、配置等。
    • 密钥表(dou_ai_key):密钥别名、过期时间、最后使用时间、失败次数等。
    • 模型表(dou_ai_model):模型名称、代码、上下文长度、最大输出 tokens 等。
    • 供应商表(dou_ai_provider):供应商名称、代码、基础地址、配置等。
    • 异步任务表(dou_ai_task):异步任务状态、请求体、结果、过期时间等。
添加日期:2026-10-05