OpenTelemetry[1] (以下簡稱 Otel)是一個開源項目,旨在為分布式追蹤、度量和日志提供統一的標準,簡化應用程序的觀測性(Observability)。它提供了一系列工具和 API,用于收集和傳輸應用程序的性能數據和日志,幫助開發者和運維團隊更好地理解系統的行為。功能包括自動和手動檢測應用程序的追蹤數據,收集關鍵度量指標,以及捕獲和傳輸日志。Otel 支持多種編程語言和框架,可以與多個后端系統集成,如 Prometheus、Jaeger、Elasticsearch 等。
Log 是 OpenTelemetry 項目的一部分,旨在提供一種標準化的方式來收集、傳輸和存儲日志數據。
Loki[2] 是 Grafana Labs[3] 開發的一個水平可擴展、高可用性、多租戶的日志聚合系統,專為效率和易用性而設計。與傳統的日志聚合系統不同,Loki 主要索引日志內容的元數據而不是內容本身,這使得它既輕量又高效。Loki 采用了與 Prometheus[4] 類似的標簽系統,使得日志查詢更加靈活和強大。常用于存儲和查詢大量日志數據,特別是與 Grafana 結合使用時,提供了強大的日志可視化和分析能力。
在本演示中將使用 Java 應用進行日志閉環操作的演示,在 Otel Log 支持的語言[5] 中,Java 是的最全面的語言之一。
圖片
安裝 Grafana helm 庫。
helm repo add grafana https://grafana.github.io/helm-chartshelm repo update
準備 Loki 的配置文件 values.yaml。
loki: auth_enabled: false commonConfig: replication_factor: 1 storage: type: 'filesystem'singleBinary: replicas: 1
安裝 Loki。
helm install --values values.yaml loki grafana/loki
安裝 Grafana。
helm install grafana grafana/grafana
通過 port forward 可以訪問 Grafana http://localhost:3000 。
POD_NAME="$(kubectl get pod -l app.kubernetes.io/name=grafana -o jsnotallow='{.items[0].metadata.name}')"kubectl --namespace default port-forward $POD_NAME 3000
在 Grafana 中配置 Loki 數據源,指向上面部署 Loki。
圖片
Otel Operator 依賴 cert-manager 進行證書的管理,安裝 operator 之前需要安裝 cert-manager。
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.2/cert-manager.yaml
執行下面命令安裝 Otel Operator
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
成功安裝 Otel Operator 之后,接下來就是配置探針的安裝和配置了,詳細的配置說明,可以參考 Instrumentation API 文檔[6]。
Instrumentation 是 Otel Operator 的另一個 CRD,用于自動安裝 Otel 探針和配置。本演示雖然主要聚焦在日志,但我們依然保留了之前使用的分布式跟蹤的配置,保證鏈路信息的傳遞。
針對 Java 應用,通過環境變量 OTEL_EXPORTER_OTLP_ENDPOINT 設置 oltp 的端點,以及 OTEL_LOGS_EXPORTER 設置應用 日志的輸出方式[7] oltp。也可以設置為 logging、oltp,將日志輸出到控制臺以及 oltp 端點。
kubectl apply -f - <<EOFapiVersion: opentelemetry.io/v1alpha1kind: Instrumentationmetadata: name: instrumentation-samplespec: propagators: - tracecontext - baggage - b3 sampler: type: parentbased_traceidratio argument: "1" env: - name: OTEL_EXPORTER_OTLP_ENDPOINT value: otel-collector.default:4318 java: env: - name: OTEL_EXPORTER_OTLP_ENDPOINT value: http://otel-collector.default:4317 - name: OTEL_LOGS_EXPORTER value: otlpEOF
在我們的設計用,Otel Collector 會將日志輸出到 Loki,實際上是通過 Loki 的 HTTP API[8] 來發送日志,因此需要使用適配 Loki API 的 exporter[9]:lokiexporter[10]。
lokiexporter 來自 Otel Collector 的 Contrib 庫[11],并不在官方的 release 中。要想在 collector 中使用 lokiexporter 有兩種方式:
Otel 收集器的詳細配置可以參考 官方文檔[14]。
kubectl apply -f - <<EOFapiVersion: opentelemetry.io/v1alpha1kind: OpenTelemetryCollectormetadata: name: otelspec: image: ghcr.io/open-telemetry/opentelemetry-collector-releases/opentelemetry-collector-contrib:0.90.1 config: | receivers: otlp: protocols: grpc: http: processors: resource: attributes: - action: insert key: loki.resource.labels value: service.name, k8s.container.name, k8s.namespace.name, k8s.pod.name exporters: debug: verbosity: detailed loki: endpoint: "http://loki.default:3100/loki/api/v1/push" tls: insecure: true default_labels_enabled: exporter: true job: true service: pipelines: logs: receivers: [otlp] processors: [resource] exporters: [loki] EOF
這是一個非常簡單的 Java 應用,監聽 8080 端口,在響應請求時打印日志。
@SpringBootApplication@Slf4j@RestControllerpublic class SpringBootRestApplication { public static void main(String[] args) { SpringApplication.run(SpringBootRestApplication.class, args); } @GetMapping("/") public String hello() { log.info("Hello World"); return "Hello World"; }}
在 Maven 的 pom 中只引入了兩個依賴 :spring-boot-starter-web 和 lombok。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> </dependency> </dependencies>
部署應用。
kubectl apply -f - <<EOFapiVersion: apps/v1kind: Deploymentmetadata: name: java-samplespec: replicas: 1 selector: matchLabels: app: java-sample template: metadata: labels: app: java-sample annotations: instrumentation.opentelemetry.io/inject-java: "true" spec: containers: - name: java-sample image: addozhang/spring-boot-rest imagePullPolicy: Always ports: - containerPort: 8080EOF
應用部署完成后,通過端口轉發可以成功訪問應用。
curl localhost:8080Hello World
Grafana 配置完 Loki 的數據源之后,在 Explore 中選擇配置的 Loki 數據源,然后在下方的 Label Filters 中選擇過濾器名 service_name 和值 java-sample。
圖片
點擊 Run query
在本文中,我們探討了如何利用 OpenTelemetry 的自動檢測功能來高效采集應用日志,通過 OpenTelemetry Collector 進行處理,并利用 Loki Exporter 將日志數據發送到 Loki。最后,我們展示了如何使用 Grafana 對這些日志進行深入的查詢和分析。這一過程不僅優化了日志管理流程,還提升了數據的可視化和可用性。這種集成為開發者和運維團隊提供了一個全面的視角,幫助他們更有效地理解和優化他們的應用和基礎設施。特別是,如果將分布式跟蹤的 traceid、spanid 等信息作為 Loki 日志的標簽,將極大地增強了日志數據的可追蹤性和可分析性。
[1] OpenTelemetry: https://opentelemetry.io
[2] Loki: https://grafana.com/oss/loki/
[3] Grafana Labs: https://grafana.com
[4] Prometheus: https://prometheus.io
[5] Otel Log 支持的語言: https://opentelemetry.io/docs/concepts/signals/logs/#language-support
[6] Instrumentation API 文檔: https://github.com/open-telemetry/opentelemetry-operator/blob/main/docs/api.md#instrumentation
[7] 日志的輸出方式: https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure#exporters
[8] Loki 的 HTTP API: https://grafana.com/docs/loki/latest/reference/api/#push-log-entries-to-loki
[9] exporter: https://opentelemetry.io/docs/collector/configuration/#exporters
[10] lokiexporter: https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/exporter/lokiexporter
[11] Otel Collector 的 Contrib 庫: https://github.com/open-telemetry/opentelemetry-collector-contrib
[12] OpenTelemetry Collector Builder (ocb): https://github.com/open-telemetry/opentelemetry-collector/tree/main/cmd/builder
[13] 官方提供的發行包 otelcol-contrib: https://github.com/open-telemetry/opentelemetry-collector-releases
[14] 官方文檔: https://opentelemetry.io/docs/collector/configuration/
本文鏈接:http://www.www897cc.com/showinfo-26-54012-0.html使用 OpenTelemetry 和 Loki 實現高效的應用日志采集和分析
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com