Skip to main content

概述

kira-otel-collector 是 Kira 所有服务统一的 tail-sampling OTLP 网关。每个服务把 100% OTLP(traces / metrics / logs)经 Fly 6PN 内网发到它,由它决定保留什么,再导出到 Dash0
观测平台只有 Dash0。 没有 BetterStack / Sentry / NATS。Dash0 的 auth token 只存在这台 collector 上DASH0_AUTH_TOKEN fly secret),各服务在 6PN 内网无需鉴权即可发到 collector。

为什么要 collector

Dash0 按发送的 span 计费,且没有 ingest 端采样(它的 “Adaptive Sampling” 只在查询期生效)。所以「保留重要的、丢弃普通的」必须发生在到 Dash0 之前 —— 这就是这台 collector 做的 tail sampling。

采样策略

信号策略
tracestail-sampled:保留 100% error trace + 100% slow(>1s)trace + 10% baseline
metrics100% 透传(聚合量,永不采样)
logs100% 透传(error 走 ERROR log,永不采样)
tail sampling 缓冲整条 trace decision_wait 时长后再裁决;各策略是 OR 关系 —— 任一策略投票保留即保留。
tail_sampling:
  decision_wait: 10s
  num_traces: 50000
  expected_new_traces_per_sec: 1000
  policies:
    - name: errors      # 100% 含 ERROR span 的 trace
      type: status_code
      status_code: { status_codes: [ERROR] }
    - name: slow        # 100% >1s 的 trace
      type: latency
      latency: { threshold_ms: 1000 }
    - name: baseline    # 其余 10%
      type: probabilistic
      probabilistic: { sampling_percentage: 10 }

部署形态

镜像otel/opentelemetry-collector-contrib:0.152.1
平台Fly.io(sjcinternal-only,单实例)
资源2 CPU / 2 GB RAM
配置otel-config.yaml,baked 进镜像
入站 OTLPgRPC [::]:4317 / HTTP [::]:4318(IPv6,Fly 6PN 是 IPv6)
健康检查TCP :13133health_check extension)
[http_service]:不暴露公网,仅经 6PN 以 kira-otel-collector.internal:4318(OTLP/HTTP)、:4317(OTLP/gRPC)被同 org 内网服务访问。

服务如何接入

把每个服务的 OTLP endpoint 指向 collector(而非 Dash0),各服务保持 AlwaysOnSampler(发 100%),由 collector 决定保留:
OTEL_EXPORTER_OTLP_ENDPOINT = http://kira-otel-collector.internal:4318
这一行在每个服务的 fly.toml [env] 里(kira-be / kira-agent / kira-cdn / kira-video-worker / kira-queue / kira-sg-billing / kira-notify / kira-auth …)。

Black-box 基础设施(Prometheus scrape)

Centrifugo 和 imgproxy 不主动推 OTLP —— collector 从它们的原生 Prometheus /metrics 端点拉取,无需 per-service sidecar:
receivertarget说明
prometheus/centrifugokira-centrifugo.internal:8000/metricsconfig.json prometheus.enabled = true
prometheus/imgproxykira-imgproxy.internal:8081/metricsIMGPROXY_PROMETHEUS_BIND=":8081",独占 RED 三件套
prometheus/collector127.0.0.1:8888/metricscollector 自身 otelcol_* 内部指标(loopback only)
拉取后用 resource/* processor 给指标打上 service.name / service.namespace=kira / deployment.environment.name=production,让它们在 Dash0 里归到正确服务下。

Pipeline

processors: memory_limiter → tail_sampling → batch   (traces)
processors: memory_limiter → batch                   (metrics / logs)
exporter:   otlphttp/dash0  (ingress.europe-west4.gcp.dash0.com, Dash0-Dataset: default)
memory_limiter(80% / spike 25%)必须最先跑,OOM 前先丢遥测。batch(8192 / 5s)聚批后导出。

环境变量(Fly secrets)

DASH0_AUTH_TOKEN     # Dash0 ingest bearer token —— 全平台仅此一份
fly.toml 不含任何 endpoint secret:Dash0 endpoint / dataset 直接写死在 otel-config.yaml,token 走 ${env:DASH0_AUTH_TOKEN}

Caveat

  • tail sampling 需要整条 trace 落到同一个 collector 实例。单实例简单但是 SPOF。要 HA 得做两层:loadbalancing exporter 按 traceID 路由 → 一池 tail-sampling collector。
  • decision_wait(10s)导致 trace 在 Dash0 里有约 10s 延迟(它要缓冲整条 trace 才能裁决)。
  • tail_sampling 在内存里缓冲在途 trace(num_traces=50000);量级增长时调大 VM 内存。