fix(readme): update
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "common-telemetry"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2024"
|
||||
description = "Microservice infrastructure library"
|
||||
|
||||
|
||||
104
README.md
104
README.md
@@ -1,6 +1,6 @@
|
||||
# Microservice Common Lib (Rust)
|
||||
|
||||
这是微服务架构的通用基础库,旨在统一所有服务的错误处理标准、日志格式以及分布式链路追踪。
|
||||
这是微服务架构的通用基础库 (`common-telemetry`),旨在统一所有服务的错误处理标准、日志格式以及分布式链路追踪。
|
||||
|
||||
## ✨ 核心特性
|
||||
|
||||
@@ -8,12 +8,14 @@
|
||||
* 基于 `thiserror` 和 `anyhow` 的最佳实践。
|
||||
* **双 Token 支持**: 明确区分 `AccessTokenExpired` (20001) 和 `RefreshTokenExpired` (20002)。
|
||||
* **Axum 集成**: 实现了 `IntoResponse`,自动将错误转换为标准 JSON 格式并设置正确的 HTTP 状态码。
|
||||
* **第三方库适配**: 提供了 `sqlx`, `redis`, `validator` 的可选集成。
|
||||
* *智能转换*: 例如 `sqlx::Error::RowNotFound` 会自动转换为 **404 Not Found**,而不是 500 Database Error。
|
||||
* **可观测性 (Telemetry)**:
|
||||
* 基于 `tracing` 生态。
|
||||
* 支持 **JSON 结构化日志** (适配 ELK/Loki)。
|
||||
* 支持 **控制台 + 文件双写**。
|
||||
* 支持 **非阻塞 (Non-blocking)** 异步日志写入与按天滚动。
|
||||
* **模块化设计**: 通过 Feature Flags 按需引入。
|
||||
* **模块化设计**: 通过 Feature Flags 按需引入,保持依赖轻量。
|
||||
|
||||
---
|
||||
|
||||
@@ -90,21 +92,21 @@ git push -u origin main
|
||||
### 1. 引入依赖
|
||||
|
||||
#### 方式 A: 通过 Kellnr 引入 (如果已发布)
|
||||
在 `user-service` 的 `Cargo.toml` 中:
|
||||
在 `user-service` 的 `Cargo.toml` 中,你可以根据需要开启 `sqlx` 或 `redis` 支持:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
# 指定 registry
|
||||
common-telemetry = { version = "0.1", registry = "kellnr", features = ["full"] }
|
||||
# 引入基础功能 + SQLX 支持
|
||||
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 地址。*
|
||||
|
||||
#### 方式 B: 通过 Gitea (Git) 引入 (简单直接)
|
||||
在 `user-service` 的 `Cargo.toml` 中:
|
||||
|
||||
#### 方式 B: 通过 Gitea (Git) 引入
|
||||
```toml
|
||||
[dependencies]
|
||||
# 指定 git 地址
|
||||
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
|
||||
use axum::{Json, response::IntoResponse};
|
||||
use common_telemetry::AppError; // 引入统一错误
|
||||
use validator::Validate;
|
||||
|
||||
async fn get_profile(token: String) -> Result<Json<UserProfile>, AppError> {
|
||||
// 模拟:Token 过期
|
||||
if token_is_expired(&token) {
|
||||
// 直接返回枚举,库会自动处理为 JSON Response (Code: 20001)
|
||||
// 并且会自动打印 Error 级别的日志
|
||||
return Err(AppError::AccessTokenExpired);
|
||||
#[derive(serde::Deserialize, Validate)]
|
||||
struct CreateUserReq {
|
||||
#[validate(email)]
|
||||
email: String,
|
||||
}
|
||||
|
||||
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 以减少编译体积:
|
||||
|
||||
| Feature | 说明 | 包含依赖 |
|
||||
| :--- | :--- | :--- |
|
||||
| **`default`** | 默认开启所有功能 | `full` |
|
||||
| **`full`** | 全功能集合 | `error`, `telemetry` |
|
||||
| **`error`** | 仅使用错误处理与 HTTP 响应 | `thiserror`, `axum`, `serde` |
|
||||
| **`telemetry`** | 仅使用日志与链路追踪 | `tracing`, `tracing-subscriber`, `tracing-appender` |
|
||||
| **`default`** | 默认开启全功能 | `full` |
|
||||
| **`full`** | 包含基础功能及所有第三方集成 | `error`, `telemetry`, `with-sqlx`, `with-redis`, `with-anyhow`, `with-validator` |
|
||||
| **`error`** | 仅使用基础错误处理 | `thiserror`, `axum`, `serde` |
|
||||
| **`telemetry`** | 仅使用日志与链路追踪 | `tracing` 全家桶 |
|
||||
| **`with-sqlx`** | 集成 `sqlx` 错误转换 | `sqlx` (自动处理 RowNotFound) |
|
||||
| **`with-redis`** | 集成 `redis` 错误转换 | `redis` |
|
||||
| **`with-validator`** | 集成 `validator` 错误转换 | `validator` |
|
||||
| **`with-anyhow`** | 集成 `anyhow` 兜底错误 | `anyhow` |
|
||||
|
||||
**示例 (只用日志模块):**
|
||||
**示例 (只用错误 + SQLX支持):**
|
||||
```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 | 枚举 | 含义 | 前端建议动作 |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `0` | `Success` | 成功 | - |
|
||||
| `10000` | `ServerError` | 服务器内部错误 | 提示“系统繁忙” |
|
||||
| `10001` | `BadRequest` | 请求参数错误 | 提示错误信息 |
|
||||
| `20000` | `Unauthorized` | 未授权/签名无效 | 跳转登录 |
|
||||
| **`20001`** | **`AccessTokenExpired`** | **Access Token 过期** | **使用 Refresh Token 静默刷新** |
|
||||
| **`20002`** | **`RefreshTokenExpired`** | **Refresh Token 过期** | **强制登出,跳转登录页** |
|
||||
| `20003` | `PermissionDenied` | 权限不足 | 提示无权访问 |
|
||||
| Code | 枚举 | HTTP | 含义 | 前端建议动作 |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
| `0` | `Success` | 200 | 成功 | - |
|
||||
| **10xxx: 基础设施** | | | | |
|
||||
| `10000` | `ServerError` | 500 | 服务器内部错误 | 提示“系统繁忙” |
|
||||
| `10001` | `DbError` | 500 | 数据库错误 | 提示“系统繁忙” |
|
||||
| `10002` | `CacheError` | 500 | 缓存服务错误 | 提示“系统繁忙” |
|
||||
| **20xxx: 认证授权** | | | | |
|
||||
| `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 | 资源已存在 | 提示“重复创建” |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user