在前一篇中(在關於 Opentelemetry 收集 log),我們引入了 opentelemetry collector 來蒐集log data,然後再傳入 Loki 服務。其實 opentelemetry collector 的作用就是在於提供一個統一的平台,來集中處理來自不同應用的遙測資料。它能夠接收來自多種遙測源的資料,進行統一的處理或轉換,然後根據需求將它們導出到合適的後端服務。因此,不管是 traces、metrics 還是 logs,都可以通過同一個 OpenTelemetry Collector 進行統一處理和轉發,這不僅減少了多個獨立數據管道的管理成本,還可以靈活應對不同的需求變化。
接下來,我們將展示如何配置 OpenTelemetry Collector 來處理 traces 和 metrics,並將它們導出到 Jaeger 和 Prometheus 中。最終,我們還會使用 Grafana 來可視化這些資料。這樣的整合方式,可以簡化我們的觀測系統,使系統更加易於管理和擴展。
在之前的 otel-collector-config.yaml
中,設定跟 Prometheus 有關的設定:
...
exporters:
prometheus:
endpoint: '0.0.0.0:9091'
...
service:
pipelines:
metrics:
receivers: [otlp]
exporters: [prometheus]
...
這段配置將通過 otel collector 接收 metrics 資料,並導出到 Prometheus。
在 docker-compose.yml
也加上 Prometheus container 的設定
self-prometheus:
image: prom/prometheus:latest
container_name: self-prometheus
ports:
- '9090:9090'
volumes:
- ./config/prometheus-local-config.yml:/etc/prometheus/prometheus.yml
networks:
- otel-network
此配置會在本地啟動 Prometheus 並將其配置文件掛載到容器中。同時要確認 prometheus.yml
這個 Prometheus config 檔案的相對路徑。
在之前的 otel-collector-config.yaml
中,設定跟 Jaeger 有關的設定:
...
exporters:
otlp:
endpoint: 'self-jaeger:4317' # 使用 Jaeger's OTLP http 接口導出tracing data
tls:
pipelines:
logs:
receivers: [otlp]
exporters: [loki]
...
service:
pipelines:
...
traces:
receivers: [otlp]
exporters: [otlp]
這邊要注意的是,在目前的 opentelemetry collector exporters中,已經沒有了jaeger
字段,所以直接用otlp
、但還是使用 jaeger endpoint。
在 docker-compose.yml
也加上 Jaeger container 的設定
self-jaeger:
container_name: self-jaeger
image: jaegertracing/all-in-one:latest
environment:
- COLLECTOR_OTLP_ENABLED=true
ports:
- '6831:6831/udp' # UDP port for Jaeger agent
- '16686:16686' # Web UI
- '14268:14268' # HTTP port for spans
networks:
- otel-network
這邊就不用把原本的 http 和 grpc 端口映射到本地主機,而是直接讓 opentelemetry-collector 透過 docker bridge 來串接。
接下來,我們可以將之前的 Node.js 應用程式補上 OpenTelemetry SDK 的 trace 和 metric 設置:
const { NodeSDK, logs } = require('@opentelemetry/sdk-node');
const {
getNodeAutoInstrumentations,
} = require('@opentelemetry/auto-instrumentations-node');
const {
OTLPMetricExporter,
} = require('@opentelemetry/exporter-metrics-otlp-http');
const {
OTLPTraceExporter,
} = require('@opentelemetry/exporter-trace-otlp-http'); // Tracing HTTP 導出器
const { OTLPLogExporter } = require('@opentelemetry/exporter-logs-otlp-http');
const { Resource } = require('@opentelemetry/resources');
const {
ATTR_SERVICE_VERSION,
ATTR_SERVICE_NAME,
} = require('@opentelemetry/semantic-conventions');
// getNodeAutoInstrumentations 會執行 instrumentation-bunyan
// 自定義服務的名稱以及版本號
const resource = new Resource({
[ATTR_SERVICE_NAME]: 'nodejs-service-demo-logs',
[ATTR_SERVICE_VERSION]: '1.0.0',
});
const logExporter = new OTLPLogExporter({
url: 'http://localhost:4318/v1/logs',
});
const metricExporter = new OTLPMetricExporter({
url: 'http://localhost:4318/v1/metrics',
headers: {},
});
const traceExporter = new OTLPTraceExporter({
url: 'http://localhost:4318/v1/traces',
});
const otelSdk = new NodeSDK({
logRecordProcessor: logExporter,
traceExporter: traceExporter,
resource,
instrumentations: [getNodeAutoInstrumentations()],
metricExporter: metricExporter,
metricInterval: 60000, // 設定採集間隔(ms)
});
otelSdk.start();
運行後,我們可以通過 Grafana 可視化這些數據。
在Grafana Connections 中,分別新增 Jaeger、Prometheus、Loki等數據源(由於我們使用docker-compose來運行,所以注意要使用docker-compose中定義的endpoint):
完成資料源配置後,可以在 Dashboard 中新增圖表,並在 Explore 中查看實時資料:
已經有很多前輩強者在鐵人賽文章中深入探討如何操作 Grafana 來達到自己需要的業務觀測效果,而本篇算是小弟個人記錄如何統一在本地使用opentelemetry collector 串接、在Grafana串接並呈現的筆記。
程式碼可以在此 Github repository 中查看。