fix(readme): update

This commit is contained in:
2026-01-29 16:04:57 +08:00
parent c5b32f721c
commit faa07b60bf
2 changed files with 68 additions and 38 deletions

View File

@@ -1,6 +1,6 @@
[package] [package]
name = "common-telemetry" name = "common-telemetry"
version = "0.1.1" version = "0.1.2"
edition = "2024" edition = "2024"
description = "Microservice infrastructure library" description = "Microservice infrastructure library"

104
README.md
View File

@@ -1,6 +1,6 @@
# Microservice Common Lib (Rust) # Microservice Common Lib (Rust)
这是微服务架构的通用基础库,旨在统一所有服务的错误处理标准、日志格式以及分布式链路追踪。 这是微服务架构的通用基础库 (`common-telemetry`),旨在统一所有服务的错误处理标准、日志格式以及分布式链路追踪。
## ✨ 核心特性 ## ✨ 核心特性
@@ -8,12 +8,14 @@
* 基于 `thiserror``anyhow` 的最佳实践。 * 基于 `thiserror``anyhow` 的最佳实践。
* **双 Token 支持**: 明确区分 `AccessTokenExpired` (20001) 和 `RefreshTokenExpired` (20002)。 * **双 Token 支持**: 明确区分 `AccessTokenExpired` (20001) 和 `RefreshTokenExpired` (20002)。
* **Axum 集成**: 实现了 `IntoResponse`,自动将错误转换为标准 JSON 格式并设置正确的 HTTP 状态码。 * **Axum 集成**: 实现了 `IntoResponse`,自动将错误转换为标准 JSON 格式并设置正确的 HTTP 状态码。
* **第三方库适配**: 提供了 `sqlx`, `redis`, `validator` 的可选集成。
* *智能转换*: 例如 `sqlx::Error::RowNotFound` 会自动转换为 **404 Not Found**,而不是 500 Database Error。
* **可观测性 (Telemetry)**: * **可观测性 (Telemetry)**:
* 基于 `tracing` 生态。 * 基于 `tracing` 生态。
* 支持 **JSON 结构化日志** (适配 ELK/Loki)。 * 支持 **JSON 结构化日志** (适配 ELK/Loki)。
* 支持 **控制台 + 文件双写** * 支持 **控制台 + 文件双写**
* 支持 **非阻塞 (Non-blocking)** 异步日志写入与按天滚动。 * 支持 **非阻塞 (Non-blocking)** 异步日志写入与按天滚动。
* **模块化设计**: 通过 Feature Flags 按需引入。 * **模块化设计**: 通过 Feature Flags 按需引入,保持依赖轻量
--- ---
@@ -90,21 +92,21 @@ git push -u origin main
### 1. 引入依赖 ### 1. 引入依赖
#### 方式 A: 通过 Kellnr 引入 (如果已发布) #### 方式 A: 通过 Kellnr 引入 (如果已发布)
`user-service``Cargo.toml` 中: `user-service``Cargo.toml`,你可以根据需要开启 `sqlx``redis` 支持
```toml ```toml
[dependencies] [dependencies]
# 指定 registry # 引入基础功能 + SQLX 支持
common-telemetry = { version = "0.1", registry = "kellnr", features = ["full"] } common-telemetry = { version = "0.1", registry = "kellnr", features = ["with-sqlx", "with-validator"] }
# 注意:你需要确保服务本身引用的 sqlx 版本与 common-telemetry 兼容
sqlx = { version = "0.7", features = ["postgres", "runtime-tokio"] }
``` ```
*注意:使用此方式,`user-service` 项目也需要在 `.cargo/config.toml` 中配置 registry 地址。* *注意:使用此方式,`user-service` 项目也需要在 `.cargo/config.toml` 中配置 registry 地址。*
#### 方式 B: 通过 Gitea (Git) 引入 (简单直接) #### 方式 B: 通过 Gitea (Git) 引入
`user-service``Cargo.toml` 中:
```toml ```toml
[dependencies] [dependencies]
# 指定 git 地址
common-telemetry = { git = "ssh://git@gitea.shay7sev.site:2222/admin/common-telemetry.git", branch = "main", features = ["full"] } common-telemetry = { git = "ssh://git@gitea.shay7sev.site:2222/admin/common-telemetry.git", branch = "main", features = ["full"] }
``` ```
@@ -137,25 +139,39 @@ async fn main() {
} }
``` ```
#### B. 错误处理与响应 (Handler) #### B. 错误处理与第三方库集成 (Handler)
由于实现了 `From<T>`,你可以直接使用 `?` 操作符,库会自动处理类型转换和 HTTP 映射。
```rust ```rust
use axum::{Json, response::IntoResponse}; use axum::{Json, response::IntoResponse};
use common_telemetry::AppError; // 引入统一错误 use common_telemetry::AppError; // 引入统一错误
use validator::Validate;
async fn get_profile(token: String) -> Result<Json<UserProfile>, AppError> { #[derive(serde::Deserialize, Validate)]
// 模拟Token 过期 struct CreateUserReq {
if token_is_expired(&token) { #[validate(email)]
// 直接返回枚举,库会自动处理为 JSON Response (Code: 20001) email: String,
// 并且会自动打印 Error 级别的日志 }
return Err(AppError::AccessTokenExpired);
async fn create_user(
Json(payload): Json<CreateUserReq>,
) -> Result<Json<String>, AppError> {
// 1. 校验错误 (自动转 AppError::ValidationError -> HTTP 400)
payload.validate()?;
// 2. 数据库查询 (自动转 AppError::DbError -> HTTP 500)
// 特殊情况:如果是 RowNotFound会自动转为 AppError::NotFound -> HTTP 404
let _user = sqlx::query!("SELECT * FROM users WHERE email = $1", payload.email)
.fetch_optional(&pool)
.await?;
// 3. 业务逻辑错误 (手动返回)
if _user.is_some() {
return Err(AppError::AlreadyExists(format!("User {} already exists", payload.email)));
} }
// 模拟:数据库错误
let user = db::find_user().await
.map_err(|e| AppError::DbError(e.to_string()))?;
Ok(Json(user)) Ok(Json("Created".into()))
} }
``` ```
@@ -163,33 +179,47 @@ async fn get_profile(token: String) -> Result<Json<UserProfile>, AppError> {
## ⚙️ 功能模块说明 (Feature Flags) ## ⚙️ 功能模块说明 (Feature Flags)
为了减少编译时间和依赖大小,你可以按需开启功能 本库采用高度模块化设计,建议按需开启 Feature 以减少编译体积
| Feature | 说明 | 包含依赖 | | Feature | 说明 | 包含依赖 |
| :--- | :--- | :--- | | :--- | :--- | :--- |
| **`default`** | 默认开启所有功能 | `full` | | **`default`** | 默认开启功能 | `full` |
| **`full`** | 全功能集合 | `error`, `telemetry` | | **`full`** | 包含基础功能及所有第三方集成 | `error`, `telemetry`, `with-sqlx`, `with-redis`, `with-anyhow`, `with-validator` |
| **`error`** | 仅使用错误处理与 HTTP 响应 | `thiserror`, `axum`, `serde` | | **`error`** | 仅使用基础错误处理 | `thiserror`, `axum`, `serde` |
| **`telemetry`** | 仅使用日志与链路追踪 | `tracing`, `tracing-subscriber`, `tracing-appender` | | **`telemetry`** | 仅使用日志与链路追踪 | `tracing` 全家桶 |
| **`with-sqlx`** | 集成 `sqlx` 错误转换 | `sqlx` (自动处理 RowNotFound) |
| **`with-redis`** | 集成 `redis` 错误转换 | `redis` |
| **`with-validator`** | 集成 `validator` 错误转换 | `validator` |
| **`with-anyhow`** | 集成 `anyhow` 兜底错误 | `anyhow` |
**示例 (只用日志模块):** **示例 (只用错误 + SQLX支持):**
```toml ```toml
common-telemetry = { version = "0.1", default-features = false, features = ["telemetry"] } common-telemetry = { version = "0.1", default-features = false, features = ["error", "with-sqlx"] }
``` ```
---
## 📝 错误码对照表 ## 📝 错误码对照表
前端开发请参考以下业务状态码 (Code) 前端开发请参考以下业务状态码 (Code)
| Code | 枚举 | 含义 | 前端建议动作 | | Code | 枚举 | HTTP | 含义 | 前端建议动作 |
| :--- | :--- | :--- | :--- | | :--- | :--- | :--- | :--- | :--- |
| `0` | `Success` | 成功 | - | | `0` | `Success` | 200 | 成功 | - |
| `10000` | `ServerError` | 服务器内部错误 | 提示“系统繁忙” | | **10xxx: 基础设施** | | | | |
| `10001` | `BadRequest` | 请求参数错误 | 提示错误信息 | | `10000` | `ServerError` | 500 | 服务器内部错误 | 提示“系统繁忙” |
| `20000` | `Unauthorized` | 未授权/签名无效 | 跳转登录 | | `10001` | `DbError` | 500 | 数据库错误 | 提示“系统繁忙” |
| **`20001`** | **`AccessTokenExpired`** | **Access Token 过期** | **使用 Refresh Token 静默刷新** | | `10002` | `CacheError` | 500 | 缓存服务错误 | 提示“系统繁忙” |
| **`20002`** | **`RefreshTokenExpired`** | **Refresh Token 过期** | **强制登出,跳转登录页** | | **20xxx: 认证授权** | | | | |
| `20003` | `PermissionDenied` | 权限不足 | 提示无权访问 | | `20000` | `Unauthorized` | 401 | 未授权/签名无效 | 跳转登录 |
| **`20001`** | **`AccessTokenExpired`** | **401** | **Access Token 过期** | **使用 Refresh Token 静默刷新** |
| **`20002`** | **`RefreshTokenExpired`** | **401** | **Refresh Token 过期** | **强制登出,跳转登录页** |
| `20003` | `PermissionDenied` | 403 | 权限不足 | 提示无权访问 |
| **30xxx: 客户端错误** | | | | |
| `30000` | `BadRequest` | 400 | 请求参数通用错误 | 提示错误信息 |
| `30001` | `ValidationError` | 400 | 表单校验失败 | 提示具体字段错误 |
| `30002` | `ResourceNotFound` | 404 | 资源不存在 | 提示“未找到数据” |
| `30003` | `ResourceAlreadyExists`| 409 | 资源已存在 | 提示“重复创建” |
--- ---