ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Aspire Dashboard 遥测 HTTP API 实战指南:OTLP JSON 端点、NDJSON 流式订阅与 aspire otel CLI 深度解析

2026/9/17 22:31:39 拓冰建站 浏览量
Aspire Dashboard 遥测 HTTP API 实战指南:OTLP JSON 端点、NDJSON 流式订阅与 aspire otel CLI 深度解析 Aspire Dashboard 遥测 HTTP API 实战指南OTLP JSON 端点、NDJSON 流式订阅与 aspire otel CLI 深度解析【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire本文围绕 Aspire 仓库中的docs/specs/dashboard-http-api.md规格文档展开系统讲解 Aspire Dashboard 暴露的遥测 HTTP API它以标准 OTLP JSON 格式返回 spans、logs 与 traces 数据支持基于有界通道的 NDJSON 实时推送并配套aspire otel命令行子命令。读完后你将能够自行配置并启用该 API、用任意 HTTP 客户端curl/脚本直接查询和订阅 Dashboard 中的遥测数据、理解其认证模式与 MCP 的关系并深入源码掌握其 O(1) 内存流式推送的实现原理。概述与设计哲学Dashboard 除了 Web UI 之外还内置了一套 REST 风格的遥测 HTTP API把 UI 中可见的同一份遥测数据spans、结构化日志、traces以标准 OTLP JSON 格式对外提供供 CLI 工具、自动化脚本和其他程序化消费者直接访问。设计上有四条核心原则见 规格文档OTLP JSON 格式响应使用标准 OpenTelemetry Protocol JSON 格式可与任意 OTLP 兼容工具互操作且直接复用 Dashboard 已有的 OTLP 导出转换逻辑RESTful 设计标准 HTTP 动词 资源导向的 URL/api/telemetry/*可配置认证支持 API Key 认证或 Unsecured 模式且与 MCP 共享同一套密钥配置推式流式传输通过 NDJSON 实现实时推送每个 watcher 仅 O(1) 内存开销。文档中给出的关键设计决策表也值得逐条理解决策选择理由响应格式OTLP JSON标准格式复用已有的TelemetryExportService流式格式NDJSONNewline Delimited JSON简单、支持广泛、易于逐行解析流式实现推式 有界通道O(1) 内存数据更新时无需重新查询端点命名/spans而非/tracesOTLP 返回的是 spanstrace 是可变的分组概念不提供/{spanId}端点改用?traceId过滤SpanId 在 trace 之间并不全局唯一配置Dashboard:Api 选项与认证模式API 通过Dashboard:Api配置节启用/禁用并设置认证方式{ Dashboard: { Api: { Enabled: true, AuthMode: ApiKey, PrimaryApiKey: your-api-key } } }设置项取值默认值说明Enabledtrue/falsetrue是否启用 Telemetry HTTP APIAuthModeApiKey/Unsecured见下文说明API 认证模式PrimaryApiKeystring-认证用的主 API KeyAuthModeApiKey时必需缺省时自动生成SecondaryApiKeystring-可选的次级 API Key用于密钥轮换几点重要说明均有源码佐证端口共享API 与 Dashboard 前端共用同一端口默认 18888无需额外监听地址。默认认证模式的真实行为从 PostConfigureDashboardOptions.cs 可以看出——当未显式开启UnsecuredAllowAnonymous时options.Api.AuthMode ?? ApiAuthMode.ApiKey即默认即为 ApiKey 模式若设置了 unsecured 选项则Api与Frontend、Otlp一起被置为 Unsecured。自动生成 Key若AuthModeApiKey但未配置PrimaryApiKeyDashboard 会用TokenGenerator生成一个随机 Key 并写回配置保证多次创建 options 实例时一致见 PostConfigureDashboardOptions.cs。Enabled / Disabled 双属性在 DashboardOptions.cs 中ApiOptions.Enabled已标记[Obsolete]推荐使用Disabled属性两者在配置层面均可用且DashboardAspireApiDisabled优先于Enabled对应的配置项见 PostConfigureDashboardOptions.cs。禁用行为当 API 被禁用时/api/telemetry/*端点根本不会被注册路由会映射为 404——见 DashboardEndpointsBuilder.cs 中的MapGetNotFound(/api/telemetry/{*path})。与 MCP 共享密钥API Key 与 MCP 配置共用设置任一方即同时生效在 Unsecured 模式下首个 API 请求到达时会记录一条警告日志。认证机制的源码级细节认证由 ApiAuthenticationHandler.cs 实现它注册为名为Api的认证方案、策略名ApiPolicy所有/api/telemetry/*端点通过RequireAuthorization(ApiAuthenticationHandler.PolicyName)统一保护见 DashboardEndpointsBuilder.cs。其校验逻辑AuthModeUnsecured时直接认证成功AuthModeApiKey时请求头必须携带恰好一个x-api-key头缺失、为空或出现多值均认证失败主 Key 匹配失败后会尝试次级 KeySecondaryApiKey这就是密钥轮换能力在源码中的落点ApiAuthenticationHandler.cs。API Key 模式下典型请求GET /api/telemetry/spans HTTP/1.1 Host: localhost:18888 X-API-Key: api-key错误响应约定状态码含义401 UnauthorizedAPI Key 缺失或无效AuthModeApiKey时404 Not Found?resource指定的资源未知或 trace 未找到端点总览与逐接口详解端点注册集中在 DashboardEndpointsBuilder.cs 的MapTelemetryApi方法中挂载于GET/POST的/api/telemetry分组下方法端点说明GET/api/telemetry/spans以 OTLP JSON 格式列出 spans支持?followtrue流式GET/api/telemetry/logs列出结构化日志支持?followtrue流式GET/api/telemetry/traces以 OTLP JSON 格式列出 traces仅快照不支持流式GET/api/telemetry/traces/{traceId}获取单个 trace 及其全部 spans此外当前实现中还注册了规格文档未详述的两个辅助端点可作为实操补充GET /api/telemetry/resources列出所有已产生遥测数据的资源含HasLogs/HasTraces/HasMetrics标记见 TelemetryApiService.cs以及POST /api/telemetry/validateToken——用浏览器 token 换取遥测 API Key便于前端页面获取调用凭据见 DashboardEndpointsBuilder.cs。GET /api/telemetry/spans查询参数与 DashboardEndpointsBuilder.cs 的绑定签名一一对应参数类型必填默认说明resourcestring否-过滤到指定资源的 spans可重复传参过滤多个资源资源不存在返回 404traceIdstring否-过滤到指定 trace ID 的 spanshasErrorbool否-true仅返回错误 spanfalse排除错误 spanlimitint否200最大返回条数从最新端截取followbool否false开启流式模式searchstring否-结构化搜索表达式当前实现额外支持可含severity:等限定符200 OK响应示例{ data: { resourceSpans: [ { resource: { attributes: [ { key: service.name, value: { stringValue: apiservice } } ] }, scopeSpans: [ { scope: { name: Aspire.Hosting }, spans: [ { traceId: 4bf92f3577b34da6a3ce929d0e0e4736, spanId: 00f067aa0ba902b7, name: GET /api/products, kind: 2, startTimeUnixNano: 1706425800000000000, endTimeUnixNano: 1706425800142000000, attributes: [ { key: http.method, value: { stringValue: GET } }, { key: http.status_code, value: { stringValue: 200 } } ], status: { code: 1 } } ] } ] } ] }, totalCount: 1500, returnedCount: 200 }从源码看limit的语义是**从最新端截取**TelemetryApiService.cs 中先取出全部匹配结果再用spans.Skip(spans.Count - effectiveLimit)保留最尾最新的limit条totalCount为匹配总数returnedCount为实际返回数。404 Not Foundresource过滤指定的资源未知时返回且响应体为带Title/Detail的 ProblemDetails见 DashboardEndpointsBuilder.cs。GET /api/telemetry/logs查询参数参数类型必填默认说明resourcestring否-过滤到指定资源的日志资源不存在返回 404traceIdstring否-过滤到指定 trace 关联的日志severitystring否-最低严重级别含该级别及以上limitint否200最大返回条数followbool否false开启流式模式searchstring否-结构化搜索表达式当前实现额外支持严重级别取值Trace、Debug、Information、Warning、Error、Critical。过滤采用大于等于逻辑——severityError同时返回 Error 与 Critical。源码印证TelemetryApiService.cs 将severity解析为LogLevel后生成FilterCondition.GreaterThanOrEqual的FieldTelemetryFilter且当级别为最低的Trace时跳过过滤全部返回。响应为200 OKdata部分为 OTLP JSON 的resourceLogs结构含timeUnixNano、severityNumber、severityText、body、attributes并可携带traceId/spanId实现日志与 trace 关联外层同样包裹totalCount/returnedCount。GET /api/telemetry/traces列出 traces仅快照不支持流式。查询参数resource可重复、hasErrortrue 仅含错误 trace / false 排除错误 trace、limit默认 100比 spans/logs 的默认 200 小对应源码常量DefaultTraceLimit 100见 TelemetryApiService.cs。实现上traces 端点先把 trace 分组展开为 span 列表traces.SelectMany(t t.Spans)再走同一个ConvertSpansToOtlpJson转换见 TelemetryApiService.cs所以响应格式与 spans 端点一致totalCount为 trace 数、returnedCount亦按 trace 数计。hasError的过滤则是通过KnownTraceFields.StatusField的Equals/NotEqual条件交给仓储层完成。GET /api/telemetry/traces/{traceId}按 ID 获取单个 trace 及其全部 spans。实现很直接仓储GetTrace(traceId)未命中则返回null端点将其转换为 404 ProblemDetailsTrace not found命中则把该 trace 的 spans 转成 OTLP JSONtotalCount与returnedCount均为 span 数见 TelemetryApiService.cs 与 DashboardEndpointsBuilder.cs。流式模式NDJSON 推送对 spans/logs 端点追加?followtrue即进入流式模式Content-Type: application/x-ndjson每行是一个完整、独立的 OTLP JSON 对象span 一行 / log 一行连接保持打开新数据实时推送推式分发每个 watcher O(1) 内存开销注意流式模式下limit参数不生效。{resourceSpans:[...]} {resourceSpans:[...]} {resourceSpans:[...]}从源码看流式响应头还有两处对实际部署很关键的细节DashboardEndpointsBuilder.cs 的StreamNdjsonAsyncCache-Control: no-cache避免代理/客户端缓存流式响应X-Accel-Buffering: no显式关闭 nginx 缓冲以保证实时性客户端断开会触发OperationCanceledException端点将其视为正常路径静默退出不会向用户输出错误。还有一个值得注意的边界能力流式订阅允许在目标资源尚未出现时就开始等待。FollowSpansAsync/FollowLogsAsync首先进入 WaitForResourceKeysAsync它先订阅OnNewResources通知再轮询GetResources()资源一旦出现即继续客户端若在资源出现前断开则直接取消。这意味着先订阅、服务后启动的用法是受支持的。响应格式OTLP JSON 包装与 NDJSON所有响应均使用标准 OpenTelemetry Protocol JSON 格式即与 OTLP exporter 的输出格式一致保证与 OpenTelemetry 生态工具兼容。Dashboard 复用的是TelemetryExportService中既有的转换方法位于 TelemetryExportService.csConvertSpansToOtlpJson()— 将 spans 集合转换为 OTLP JSONConvertLogsToOtlpJson()— 将 logs 转换为 OTLP JSONConvertSpanToJson()— 将单个 span 转换为 JSON 字符串供 NDJSON 逐行输出使用见 TelemetryApiService.cs。列表端点在 OTLP 数据外层包裹了计数信息便于调用方判断是否有未取回的数据{ data: { }, // OTLP JSONresourceSpans 或 resourceLogs totalCount: 1500, // 仓储中匹配的条目总数 returnedCount: 200 // 实际返回受 limit 限制的条目数 }流式端点则没有包装——每行即原始 OTLP JSON天然适配curl、jq与流式解析器。推式流式架构有界通道的实现原理规格文档 Part 3 描述的推式架构在源码中可以逐条对应核心位于 SqliteTelemetryRepository.Runtime.cs 的WatchSpansAsync/WatchLogsAsync约 L217、L274 起Watcher 注册客户端开始流式时创建一个Channel.CreateBounded的有界通道——容量1000、FullMode DropOldest见 L221-L223 与 L278-L280并将 watcher 加入_spanWatchers/ 日志侧的 watcher 列表推送即投递新 span/log 写入仓储时直接遍历 watcher 列表向各通道TryWrite消费端无需轮询去重使用 span/log ID 的HashSetstring消除初始快照与后续推送之间的重复惰性初始化watcher 列表在首个订阅者出现前不分配_spanWatchers ?? []见 L229-L230无订阅者时零开销清理watcher 在finally中移除通道在释放时完成客户端断开不会泄漏订阅。配合DropOldest语义慢消费者网络慢、处理慢只会丢掉最旧的积压项而不会阻塞写路径这正是O(1) 内存、不反压设计决策的落地方式。CLI 集成aspire otel 命令组Aspire CLI 中的遥测操作以otel命令组暴露。仓库源码中TelemetryCommand.cs 定义了名为otel的父命令挂接logs、spans、traces三个子命令帮助分组归入 Monitoringaspire otel logs [resource] [options] aspire otel spans [resource] [options] aspire otel trace [traceId] [options]aspire otel logs列出或流式订阅结构化日志aspire otel logs # 最近的日志 aspire otel logs frontend # frontend 服务的日志 aspire otel logs --severity error # Error 及以上级别 aspire otel logs --trace-id 4bf92f... # 与某个 trace 关联的日志 aspire otel logs --follow # 实时流式 aspire otel logs --limit 50 # 限制结果条数 aspire otel logs --json # 输出原始 OTLP JSON标志说明--severity最低严重级别Trace/Debug/Information/Warning/Error/Critical--trace-id过滤到指定 trace 的日志--follow数据到达即流式输出--limit最大返回条数--has-error过滤到错误日志--json输出原始 OTLP JSONaspire otel spans列出或流式订阅原始 spans面向高级用户/脚本场景aspire otel spans # 最近的 spans aspire otel spans catalogdb # catalogdb 服务的 spans aspire otel spans --trace-id 4bf92f... # 某个 trace 内的 spans aspire otel spans --has-error # 仅失败的 spans aspire otel spans --follow # 实时流式 aspire otel spans --json | jq ... # 管道给 jq 等工具标志说明--trace-id过滤到指定 trace 的 spans--followspan 到达即流式输出--limit最大返回条数--has-error过滤到错误状态的 spans--json输出原始 OTLP JSONaspire otel trace列出 traces 或展示单个 trace 的瀑布图快照模式不支持流式aspire otel trace # 列出最近的 traces aspire otel trace 4bf92f3577b34d # 展示瀑布视图 aspire otel trace --has-error # 仅失败的 traces aspire otel trace 4bf92f... --logs # 附带关联日志Trace 列表输出TRACE ID DURATION SERVICES ROOT SPAN STATUS 4bf92f3577b34d 142ms frontend→api→db GET /api/products ✓ c21a35b944... 3.7s catalogdb→postgres Initializing catalog ✓ 28336000bd... 87ms orderprocessor→rabbit rabbitmq connect ✓Trace 瀑布输出┌─ frontend (52ms) │ GET /api/products │ ├──┬─ apiservice (48ms) │ │ GET /api/products │ │ │ └──┬─ catalogdb (12ms) │ │ SELECT * FROM products │ │ │ └─ catalogdb (3ms) │ SELECT * FROM inventory标志说明--limit列出的最大 trace 数--has-error过滤含错误的 traces--logs展示指定 trace 时附带关联日志--json输出原始 OTLP JSON流式支持矩阵命令--follow说明otel logs✅语义自然类似tail -fotel spans✅span 到达即流式输出otel trace❌trace 是分组概念没有完成信号不适合流式实现路径与通信模型各命令到 API 的映射是一对一的直连调用logs→GET /api/telemetry/logsspans→GET /api/telemetry/spanstrace列表 →GET /api/telemetry/tracestrace详情 →GET /api/telemetry/traces/{traceId}。CLI 并不自己猜Dashboard 地址和密钥。其通信模型是CLI 通过 Backchannel 向 AppHost 发起GetDashboardInfo()拿到 Dashboard URL 与 API Token随后携带X-API-Key直接对 Dashboard 发起 HTTP 调用┌─────────┐ ┌─────────┐ ┌───────────┐ │ CLI │─── Backchannel ─────▶│ AppHost │ │ Dashboard │ │ │ GetDashboardInfo() │ │ │ │ │ │◀─── URL Token ─────│ │ │ │ │ │ └─────────┘ │ │ │ │ │ │ │ │─────────────── HTTP GET /api/telemetry/spans ──────▶│ │ │ │ X-API-Key: token │ │ │ │◀──────────────────── JSON Response ─────────────────│ │ └─────────┘ └───────────┘与 MCP 的对比Dashboard 的同一份遥测数据同时通过 MCPJSON-RPC over SSE与 HTTP APIREST两种通道暴露且两者共享同一 API Key 认证。差异如下维度MCPHTTP API协议JSON-RPC over SSEREST over HTTP认证X-API-Key头相同响应格式文本内嵌 JSONOTLP JSON流式支持SSE支持NDJSON客户端要求需要 MCP SDK任意 HTTP 客户端典型场景AI 助手CLI、自动化、脚本简言之给 AI Agent 用选 MCP给脚本/CI/自定义工具用选 HTTP API。测试覆盖该 API 在仓库中拥有相当完整的测试矩阵集成测试— tests/Aspire.Dashboard.Tests/Integration/TelemetryApiTests.cs规格文档列出 25 个用例SpansGetSpans_UnsecuredMode_Returns200、GetSpans_WithQueryParameters_Returns200、GetSpans_WithUnknownResource_Returns404、GetSpans_WithApiKey_Returns200、GetSpans_WithWrongApiKey_ReturnsUnauthorized、GetSpans_WithSecondaryApiKey_Returns200、GetSpans_McpKeyFallback_Returns200、GetSpans_StreamingMode_ReturnsNdjsonContentTypeLogsGetLogs_UnsecuredMode_Returns200、GetLogs_WithTraceIdFilter_Returns200、GetLogs_WithUnknownResource_Returns404、GetLogs_WithApiKey_Returns200、GetLogs_WithWrongApiKey_ReturnsUnauthorized、GetLogs_StreamingMode_ReturnsNdjsonContentTypeTracesGetTraces_UnsecuredMode_Returns200、GetTraces_WithHasErrorFilter_Returns200、GetTraces_WithUnknownResource_Returns404、GetTraceById_NotFound_Returns404、GetTraces_WithApiKey_Returns200配置Configuration_ApiAuthModeDefaults_WhenNotConfigured、Configuration_ApiKeyFromMcp_CopiedToApi、Configuration_ApiKeyExplicit_OverridesMcp、Configuration_ApiEnabled_DefaultsToTrue、Configuration_ApiDisabled_Returns404单元测试— tests/Aspire.Dashboard.Tests/TelemetryApiServiceTests.cs6 个用例FollowSpansAsync_StreamsAllSpans、FollowLogsAsync_StreamsAllLogs、GetSpans_HasErrorFalse_ExcludesErrorSpans、GetSpans_HasErrorTrue_OnlyReturnsErrorSpans、GetTraces_HasErrorFalse_ExcludesTracesWithErrors、GetTraces_HasErrorTrue_OnlyReturnsTracesWithErrors。仓储 watcher 测试— tests/Aspire.Dashboard.Tests/TelemetryRepositoryTests/TelemetryRepositoryTests.cs7 个用例WatchSpansAsync_ReturnsExistingSpans_ThenNewSpans、WatchSpansAsync_CanBeCancelled、WatchSpansAsync_FiltersById_WhenResourceKeyProvided、WatchLogsAsync_ReturnsExistingLogs_ThenNewLogs、WatchLogsAsync_CanBeCancelled、WatchLogsAsync_FiltersAppliedWhenPushing、WatchLogsAsync_SeverityFilterApplied。这些用例恰好覆盖了本文重点认证三种路径主 Key/次 Key/MCP 回退、404 边界、NDJSON 内容类型、hasError双向过滤语义、以及 watcher 的先存量后增量行为。后续规划规格文档还给出了两个演进方向供集成方做长期规划时参考Metrics指标支持加入后预计新增GET /api/telemetry/metrics与GET /api/telemetry/metrics/{metricName}分页面向大数据集可能引入基于游标的分页形如GET /api/telemetry/logs?limit100after12345。关键文件索引文件职责src/Aspire.Dashboard/Api/TelemetryApiService.csAPI 服务查询、过滤、流式订阅的业务逻辑src/Aspire.Dashboard/Api/ApiAuthenticationHandler.csAPI MCP 共享的 API Key 认证处理器src/Aspire.Dashboard/DashboardEndpointsBuilder.cs/api/telemetry/*端点注册与 NDJSON 流式写出src/Aspire.Dashboard/Configuration/DashboardOptions.csApiOptionsEnabled/Disabled、AuthMode、主/次 Keysrc/Aspire.Dashboard/Configuration/PostConfigureDashboardOptions.cs默认值填充、Key 自动生成、MCP 密钥共享src/Aspire.Dashboard/Otlp/Storage/SqliteTelemetryRepository.Runtime.csWatchSpansAsync/WatchLogsAsync推式订阅实现src/Aspire.Dashboard/Model/TelemetryExportService.csOTLP JSON 转换src/Aspire.Cli/Commands/TelemetryCommand.csaspire otel命令组入口docs/specs/dashboard-http-api.md本文所依据的规格文档适用前提与限制小结以上所有行为均以当前仓库实现为准——API 默认随 Dashboard 启用且默认 ApiKey 认证Key 可自动生成traces 端点无流式NDJSON 流式不支持limit?resource支持重复传参过滤多个资源Unsecured 模式仅建议本地可信环境使用。【免费下载链接】aspireAspire is the tool for code-first, extensible, observable dev and deploy.项目地址: https://gitcode.com/GitHub_Trending/as/aspire创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考