Skip to main content

tdm_server_rust/dev/
error_repo.rs

1//! dev 错误 MySQL 落库
2
3use chrono::{DateTime, Utc};
4use serde::Serialize;
5use sqlx::FromRow;
6
7/// dev_error_log 表行
8#[derive(Debug, Clone, Serialize, FromRow)]
9pub struct DevErrorRow {
10    /// 主键
11    pub id: i64,
12    /// 创建时间
13    pub created_at: DateTime<Utc>,
14    /// 错误类型
15    pub kind: String,
16    /// HTTP 方法
17    pub method: Option<String>,
18    /// 请求路径
19    pub path: Option<String>,
20    /// HTTP 状态码
21    pub status: Option<i16>,
22    /// 业务错误码
23    pub code: Option<i32>,
24    /// 摘要
25    pub msg: String,
26    /// 组员 ID
27    pub member_id: Option<i32>,
28    /// OTel trace id(32 hex)
29    pub otel_trace_id: Option<String>,
30}
31
32/// 写入参数
33#[derive(Debug, Clone)]
34pub struct DevErrorInsert {
35    /// 错误类型
36    pub kind: &'static str,
37    /// HTTP 方法
38    pub method: Option<String>,
39    /// 路径
40    pub path: Option<String>,
41    /// HTTP 状态
42    pub status: Option<i16>,
43    /// 业务码
44    pub code: Option<i32>,
45    /// 消息
46    pub msg: String,
47    /// 组员 ID
48    pub member_id: Option<i32>,
49    /// trace id
50    pub otel_trace_id: Option<String>,
51}
52
53/// 插入 dev 错误记录
54#[tracing::instrument(skip_all, level = "info", fields(kind = row.kind))]
55pub async fn insert(pool: &sqlx::PgPool, row: DevErrorInsert) -> sqlx::Result<()> {
56    sqlx::query(
57        r#"INSERT INTO dev_error_log
58        (kind, method, path, status, code, msg, member_id, otel_trace_id)
59        VALUES ($1, $2, $3, $4, $5, $6, $7, $8)"#,
60    )
61    .bind(row.kind)
62    .bind(row.method)
63    .bind(row.path)
64    .bind(row.status)
65    .bind(row.code)
66    .bind(row.msg)
67    .bind(row.member_id)
68    .bind(row.otel_trace_id)
69    .execute(pool)
70    .await?;
71    Ok(())
72}
73
74/// 查询最近错误
75#[tracing::instrument(skip_all, level = "info")]
76pub async fn list_recent(pool: &sqlx::PgPool, limit: i64) -> sqlx::Result<Vec<DevErrorRow>> {
77    sqlx::query_as::<_, DevErrorRow>(
78        r#"SELECT id, created_at, kind, method, path, status, code, msg, member_id, otel_trace_id
79           FROM dev_error_log ORDER BY id DESC LIMIT $1"#,
80    )
81    .bind(limit)
82    .fetch_all(pool)
83    .await
84}
85
86/// 按 id 查询
87#[tracing::instrument(skip_all, level = "info")]
88pub async fn find_by_id(pool: &sqlx::PgPool, id: i64) -> sqlx::Result<Option<DevErrorRow>> {
89    sqlx::query_as::<_, DevErrorRow>(
90        r#"SELECT id, created_at, kind, method, path, status, code, msg, member_id, otel_trace_id
91           FROM dev_error_log WHERE id = $1"#,
92    )
93    .bind(id)
94    .fetch_optional(pool)
95    .await
96}