# 14_OpenTelemetry 接入指引

> 现状：Admin/Mini/User API 已集成 OTel 埋点，可导出到 Collector/控制台/文件日志，默认关闭 OTLP 导出。

## 1. 依赖与版本
- NuGet：`OpenTelemetry.Extensions.Hosting`、`OpenTelemetry.Instrumentation.AspNetCore`、`OpenTelemetry.Instrumentation.Http`、`OpenTelemetry.Instrumentation.EntityFrameworkCore`、`OpenTelemetry.Instrumentation.Runtime`、`OpenTelemetry.Exporter.OpenTelemetryProtocol`、`OpenTelemetry.Exporter.Console`。
- 当前 EF Core instrumentation 由 NuGet 回退到 `1.10.0-beta.1`（会提示 NU1603/NU1902），待可用时统一升级到稳定版以消除告警。

## 2. 程序内配置（Admin/Mini/User API）
- Resource：`ServiceName` 分别为 `TakeoutSaaS.AdminApi|MiniApi|UserApi`，`ServiceInstanceId = Environment.MachineName`。
- Tracing：开启 ASP.NET Core、HttpClient、EF Core（禁用 SQL 文本）、Runtime；采样器默认 `ParentBased + AlwaysOn`。
- Metrics：开启 ASP.NET Core、HttpClient、Runtime。
- Exporter：
  - OTLP（可选）：读取 `Otel:Endpoint`，非空时启用。
  - Console：`Otel:UseConsoleExporter`（默认 Dev 开启，Prod 关闭）。
- 日志：Serilog 输出 Console + 文件（按天滚动，保留 7 天），模板已包含 TraceId/SpanId（通过 Enrich FromLogContext）。

## 3. appsettings 配置键
```json
"Otel": {
  "Endpoint": "",                 // 为空则不推 OTLP，例如 http://otel-collector:4317
  "Sampling": "ParentBasedAlwaysOn",
  "UseConsoleExporter": true      // Dev 默认 true，Prod 建议 false
}
```
- 环境变量可覆盖：`OTEL_SERVICE_NAME`、`OTEL_EXPORTER_OTLP_ENDPOINT` 等。

## 4. Collector/后端接入建议
- Collector 监听 4317/4318（gRPC/HTTP OTLP），做采样/脱敏/分流，再转发 Jaeger/Tempo/ELK/Datadog 等。
- 生产注意：限制导出 SQL 文本（已关闭）、对敏感字段脱敏，必要时在 Collector 做 TraceIdRatioBased 采样以控量。

## 5. 验证步骤
1) 开启 `Otel:UseConsoleExporter=true`，本地运行 API，观察控制台是否输出 Span/Metric。  
2) 配置 `Otel:Endpoint=http://localhost:4317` 并启动 Collector，使用 Jaeger/Tempo UI 或 `curl http://localhost:4318/v1/traces` 验证链路。  
3) 文件日志：查看 `logs/admin-api-*.log` 等，确认包含 TraceId/SpanId。

## 6. 后续工作
- 待 NuGet 源更新后，升级到稳定版 OTel 包并消除 NU1603/NU1902 告警。  
- 如需采集日志到 ELK，可直接用 Filebeat/Vector 读取 `logs/*.log` 推送，无需改代码。  
- 如需控制采样率或关闭某些 instrumentation，调整 appsettings 中的 Sampling/开关后重启即可。
