Hyz.Trace.Dashboard
1.0.0
dotnet add package Hyz.Trace.Dashboard --version 1.0.0
NuGet\Install-Package Hyz.Trace.Dashboard -Version 1.0.0
<PackageReference Include="Hyz.Trace.Dashboard" Version="1.0.0" />
<PackageVersion Include="Hyz.Trace.Dashboard" Version="1.0.0" />
<PackageReference Include="Hyz.Trace.Dashboard" />
paket add Hyz.Trace.Dashboard --version 1.0.0
#r "nuget: Hyz.Trace.Dashboard, 1.0.0"
#:package Hyz.Trace.Dashboard@1.0.0
#addin nuget:?package=Hyz.Trace.Dashboard&version=1.0.0
#tool nuget:?package=Hyz.Trace.Dashboard&version=1.0.0
Hyz.Trace.Dashboard
链路追踪 Dashboard 中间件,提供嵌入式 Web UI 面板、HTTP/gRPC 双协议数据摄入端点和 RESTful 管理 API。类似 Swagger UI,无需额外服务,一行代码集成到 ASP.NET Core 应用。
目标框架
- net8.0 / net9.0 / net10.0
功能特性
- 嵌入式 Web UI — Vue 3 单页应用,从嵌入式资源加载,无需额外静态文件部署
- 双协议摄入 — HTTP JSON 和 gRPC Protobuf 客户端流式两种上报方式
- RESTful 管理 API — Trace 查询、统计聚合、应用管理、用户管理、安全设置
- 用户认证系统 — HttpOnly Cookie + JWT,首次部署引导注册管理员
- API Key 安全机制 — 应用与密钥合一,SHA256 哈希存储,明文仅创建/重置时返回一次
- 多应用数据隔离 — 通过 API Key 确定应用归属,ApplicationId 隔离数据
- 自动路径排除 — 中间件自动排除 Dashboard 路径防止递归追踪
- 健康检查 —
/api/health端点供负载均衡器使用 - Prometheus 指标 —
/metrics/{key}端点,密钥保护 - gRPC 可选启用 — 默认不注册 gRPC 端点,需显式配置开启
- 进程内模式支持 — 配合 DashboardExporter 实现应用内嵌 Dashboard
快速开始
1. 安装 NuGet 包
dotnet add package Hyz.Trace.Dashboard
还需要安装存储实现包:
# 使用 FreeSql(SQLite/MySQL/PostgreSQL)
dotnet add package Hyz.Trace.Storage.FreeSql
# 或使用 ClickHouse(大规模部署)
dotnet add package Hyz.Trace.Storage.ClickHouse
2. 注册服务
using Hyz.Trace.Dashboard;
using Hyz.Trace.Storage;
var builder = WebApplication.CreateBuilder(args);
// 注册存储(SQLite 示例)
builder.Services.UseSqliteStorage("Data Source=traces.db");
// 注册 Dashboard 所需服务
builder.Services.AddSingleton<RuntimeConfigStore>();
// 如需 gRPC 摄入端点
// builder.Services.AddGrpc();
var app = builder.Build();
3. 启用中间件
// 启用 Dashboard 面板(默认路径 /trace-dashboard)
app.UseTraceDashboard();
// 如果启用了 gRPC
// app.MapGrpcService<TraceIngestGrpcService>();
app.Run();
启动后访问 http://localhost:5000/trace-dashboard 即可。首次访问会引导创建管理员账户。
配置选项(TraceDashboardOptions)
通过 UseTraceDashboard(options => { ... }) 配置:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
Path |
string | "/trace-dashboard" |
Dashboard 访问路径 |
Enabled |
bool | true |
是否启用 Dashboard |
app.UseTraceDashboard(options =>
{
options.Path = "/admin/traces"; // 自定义路径
options.Enabled = true;
});
注意:配置自定义路径后,ASP.NET Core 追踪中间件(
app.UseTrace())会自动从TraceDashboardOptions.Path读取路径并排除该前缀下的请求,防止递归追踪。
API 端点
所有 API 端点以 {Path}/api 为前缀(默认为 /trace-dashboard/api)。
数据摄入端点(无需登录,API Key 自认证)
| 方法 | 路径 | 说明 | 认证方式 |
|---|---|---|---|
| POST | /traces/ingest |
HTTP 批量摄入 Span | x-trace-api-key 请求头(兼容 X-API-Key) |
| POST | /client/register |
兼容旧版客户端自注册(记录警告) | API Key |
| GET | /health |
Dashboard API 健康检查 | 无 |
健康检查(Dashboard 路径外)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/health |
全局健康检查(负载均衡器使用,无认证) |
认证端点
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /auth/register |
首次注册管理员账户 |
| POST | /auth/login |
登录(设置 HttpOnly Cookie,24小时有效期) |
| POST | /auth/logout |
登出(清除 Cookie) |
| GET | /auth/status |
获取当前登录状态 |
查询端点(需要登录)
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /traces |
分页查询 Trace 列表(支持 status/method/application/from/to/httpStatus/minDuration/tag_* 筛选) |
| GET | /traces/recent |
最近 N 条 Trace |
| GET | /trace/{traceId} |
获取 Trace 完整详情(Span 树) |
| GET | /trace/{traceId}/similar |
相似 Trace 查询 |
| GET | /applications |
获取所有应用名称列表 |
| GET | /stats |
统计概览 |
| GET | /dashboard/overview |
Dashboard 概览(KPI + 趋势 + 热力图 + 应用健康状态) |
| GET | /dashboard/kpi |
KPI 指标(总请求数/错误率/P99/活跃应用数/告警数) |
| GET | /dashboard/trend |
请求量/错误数/平均延迟趋势 |
| GET | /dashboard/latency-trend |
P50/P75/P90/P95/P99 延迟趋势 |
| GET | /dashboard/application/{name} |
单应用详情指标 |
| GET | /dashboard/endpoints |
接口性能排行 |
| GET | /topology |
服务拓扑(节点+边,支持 service/method 级别) |
| GET | /aggregation |
链路聚合(相似 Trace 分组 + 延迟分布热力图) |
| GET | /aggregation/slow-spans |
慢 Span 分析(支持 threshold/limit/page/pageSize) |
| GET | /aggregation/slow-traces |
慢 Trace 分析 |
| GET | /errors/issues |
错误聚类(支持 application/errorType/keyword/page/pageSize/from/to) |
| GET | /errors/trend |
错误趋势 |
| GET | /apps |
应用列表(含密钥前缀) |
| GET | /apps/query |
应用分页查询 |
| GET | /settings |
获取系统设置 |
| PUT | /settings |
更新系统设置 |
管理员端点
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /users |
用户列表 |
| GET | /users/query |
用户分页查询 |
| POST | /users |
创建用户(固定 User 角色,密码返回后哈希存储) |
| PUT | /users/{id} |
更新用户信息 |
| DELETE | /users/{id} |
删除用户(不能删除管理员) |
| PUT | /users/{id}/enable |
启用/禁用用户 |
| POST | /apps |
创建应用(自动生成 API Key,明文仅返回一次) |
| PUT | /apps/{id} |
更新应用信息 |
| DELETE | /apps/{id} |
删除应用 |
| POST | /apps/{id}/reset-key |
重置应用 API Key(旧 Key 立即失效) |
| GET | /security/metrics-key |
获取 Prometheus 端点密钥 |
| PUT | /security/metrics-key |
更新 Prometheus 端点密钥 |
| POST | /security/metrics-key/regenerate |
重新生成 Prometheus 端点密钥 |
| DELETE | /traces |
清空所有追踪数据 |
| DELETE | /trace/{traceId} |
删除指定 Trace |
gRPC 摄入
启用 gRPC 后注册 TraceIngestGrpcService,提供 ReportSpans 客户端流式方法。metadata 中需携带 x-trace-api-key。
builder.Services.AddGrpc();
// ...
app.MapGrpcService<Hyz.Trace.Dashboard.TraceIngestGrpcService>();
必须在 appsettings.json 中显式启用:
{
"TraceServer": {
"EnableGrpc": true
}
}
进程内模式(InProcess)
Dashboard 中间件配合 DashboardExporter 可实现进程内追踪(数据直接写入本地存储,无需网络上报)。
基本用法(默认应用)
builder.Services.UseSqliteStorage("Data Source=traces.db");
builder.Services.AddSingleton<RuntimeConfigStore>();
builder.AddTrace(options =>
{
options.Enabled = true;
options.DashboardProtocol = ReportProtocol.InProcess;
})
.AddTraceReporting(); // 自动注册 DashboardExporter(无 API Key 绑定)
// ...
app.UseTrace();
app.UseTraceDashboard();
推荐用法(绑定 API Key 应用)
builder.Services.UseSqliteStorage("Data Source=traces.db");
builder.Services.AddSingleton<RuntimeConfigStore>();
// 手动注册 DashboardExporter,传入 apiKey 实现应用绑定
builder.Services.AddSingleton<ITraceExporter>(sp =>
{
var repository = sp.GetRequiredService<ITraceRepository>();
var appRepository = sp.GetRequiredService<IApplicationRepository>();
return new DashboardExporter(repository, appRepository, "trk_xxxxxxxxxxxxxxxx");
});
builder.AddTrace(options =>
{
options.Enabled = true;
options.DashboardProtocol = ReportProtocol.InProcess;
});
// 注意:不要调用 .AddTraceReporting(),因为已手动注册 DashboardExporter
重要:传入 apiKey 时,DashboardExporter 构造函数会立即查找绑定的应用。如果密钥无效或应用被禁用,会直接抛出异常(Fail Fast),防止数据写入错误的应用。
摄入请求格式(HTTP)
POST /trace-dashboard/api/traces/ingest
Content-Type: application/json
x-trace-api-key: trk_xxxxxxxxxxxxxxxx
[
{
"traceId": "string",
"spanId": "string",
"parentSpanId": "string|null",
"methodName": "string",
"startTimeUtc": "ISO8601",
"durationMs": number,
"status": "Ok|Error",
"tagsJson": "string|null",
"inputParameters": "string|null",
"returnValue": "string|null",
"errorMessage": "string|null",
"errorType": "string|null",
"errorStack": "string|null",
"requestHeaders": "string|null",
"httpMethod": "string|null",
"httpPath": "string|null",
"httpRoute": "string|null",
"httpStatusCode": number|null,
"peerService": "string|null",
"isRoot": boolean
}
]
客户端不应发送 applicationId 或 applicationName 字段。服务端通过 API Key 的 SHA256 哈希自动查找绑定的应用,并强制设置 ApplicationId。客户端传入的应用信息将被忽略。
应用与密钥管理
应用与密钥在设计上合为一体:
- 创建应用时自动生成唯一 API Key(
trk_前缀 + 24 位随机字符) - 密钥存储:仅保存 SHA256 哈希和前缀(前 12 位明文),不保存完整明文
- 密钥展示:列表中显示前缀用于识别(如
trk_a1b2c3d4e5f6...) - 一次明文:创建/重置时密钥明文仅在响应中返回一次,请立即保存
- 重置密钥:旧密钥立即失效,新密钥同样仅明文返回一次
- 应用归属:所有上报 Span 通过 API Key 确定 ApplicationId,多应用数据自动隔离
- 应用禁用:禁用应用后该密钥的上报请求返回 403 Forbidden
认证机制
- 认证方式:HttpOnly Cookie(
HyzTraceAuth),内含 JWT Token - Token 有效期:24 小时
- 首次部署:无用户时自动开放注册端点,创建第一个管理员账户
- 权限控制:
- 普通用户:查看 Trace、统计、应用列表
- 管理员:用户管理、应用管理、密钥重置、数据删除
- 管理员保护:管理员账户不能被删除或禁用
依赖关系
Hyz.Trace— 核心追踪引擎(依赖)Hyz.Trace.Storage.Abstractions— 存储抽象层(依赖)Hyz.Trace.Reporting.Abstractions— 上报抽象层(DashboardExporter 实现 ITraceExporter)Microsoft.AspNetCore.App— ASP.NET Core 框架BCrypt.Net-Next— 密码哈希Grpc.AspNetCore— gRPC 服务(可选,启用 gRPC 时需要)
与 Hyz.Trace.Server 的关系
Hyz.Trace.Dashboard是可嵌入的中间件包,可集成到任何 ASP.NET Core 应用Hyz.Trace.Server是基于此中间件构建的独立可部署服务端程序,提供完整的多存储支持、配置体系、NLog 日志、gRPC 可选启用等开箱即用功能- 如果只需要在现有应用中嵌入 Dashboard,直接使用
Hyz.Trace.Dashboard即可 - 如果需要独立部署的追踪服务端,使用
Hyz.Trace.Server
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- BCrypt.Net-Next (>= 4.2.0)
- Castle.Core (>= 5.2.1)
- Google.Protobuf (>= 3.28.2)
- Grpc.AspNetCore (>= 2.66.0)
- Grpc.Net.Client (>= 2.66.0)
- Hyz.Trace (>= 1.0.0)
- Hyz.Trace.Storage.Abstractions (>= 1.0.0)
-
net8.0
- BCrypt.Net-Next (>= 4.2.0)
- Castle.Core (>= 5.2.1)
- Google.Protobuf (>= 3.28.2)
- Grpc.AspNetCore (>= 2.66.0)
- Grpc.Net.Client (>= 2.66.0)
- Hyz.Trace (>= 1.0.0)
- Hyz.Trace.Storage.Abstractions (>= 1.0.0)
-
net9.0
- BCrypt.Net-Next (>= 4.2.0)
- Castle.Core (>= 5.2.1)
- Google.Protobuf (>= 3.28.2)
- Grpc.AspNetCore (>= 2.66.0)
- Grpc.Net.Client (>= 2.66.0)
- Hyz.Trace (>= 1.0.0)
- Hyz.Trace.Storage.Abstractions (>= 1.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.