首页 > 其他分享 >使用 OpenTelemetry 和 Loki 实现高效的应用日志采集和分析

使用 OpenTelemetry 和 Loki 实现高效的应用日志采集和分析

时间:2023-12-25 12:32:22浏览次数:39  
标签:kubectl Otel Grafana OpenTelemetry Loki 日志

在之前的文章陆续介绍了 如何在 Kubernetes 中使用 Otel 的自动插桩 以及 Otel 与 服务网格协同实现分布式跟踪,这两篇的文章都将目标聚焦在分布式跟踪中,而作为可观测性三大支柱之一的日志也是我们经常使用的系统观测手段,今天这篇文章就来体验下应用日志的操作闭环。

背景

OpenTelemetry 简介

OpenTelemetry (以下简称 Otel)是一个开源项目,旨在为分布式追踪、度量和日志提供统一的标准,简化应用程序的观测性(Observability)。它提供了一系列工具和 API,用于收集和传输应用程序的性能数据和日志,帮助开发者和运维团队更好地理解系统的行为。功能包括自动和手动检测应用程序的追踪数据,收集关键度量指标,以及捕获和传输日志。Otel 支持多种编程语言和框架,可以与多个后端系统集成,如 Prometheus、Jaeger、Elasticsearch 等。

Log 是 OpenTelemetry 项目的一部分,旨在提供一种标准化的方式来收集、传输和存储日志数据。

Loki 简介

LokiGrafana Labs 开发的一个水平可扩展、高可用性、多租户的日志聚合系统,专为效率和易用性而设计。与传统的日志聚合系统不同,Loki 主要索引日志内容的元数据而不是内容本身,这使得它既轻量又高效。Loki 采用了与 Prometheus 类似的标签系统,使得日志查询更加灵活和强大。常用于存储和查询大量日志数据,特别是与 Grafana 结合使用时,提供了强大的日志可视化和分析能力。

演示

在本演示中将使用 Java 应用进行日志闭环操作的演示,在 Otel Log 支持的语言 中,Java 是的最全面的语言之一。

架构

  1. Otel Operator 通过自动插桩的配置,为 Java 工作负载安装探针并加载配置
  2. 应用通过 otlp 端点上报日志到 Otel collector
  3. Otel collector 将日志输出到 Loki
  4. grafana 将 Loki 作为数据源进行日志的可视化展示

前置条件

  • Kubernetes 集群
  • kubectl cli
  • helm cli

安装 Loki 和 Grafana

安装 Grafana helm 库。

helm repo add grafana https://grafana.github.io/helm-charts
helm 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 jsonpath='{.items[0].metadata.name}')"
kubectl --namespace default port-forward $POD_NAME 3000

在 Grafana 中配置 Loki 数据源,指向上面部署 Loki。

安装 Otel Operator

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

配置 Instrumentation

成功安装 Otel Operator 之后,接下来就是配置探针的安装和配置了,详细的配置说明,可以参考 Instrumentation API 文档

Instrumentation 是 Otel Operator 的另一个 CRD,用于自动安装 Otel 探针和配置。本演示虽然主要聚焦在日志,但我们依然保留了之前使用的分布式跟踪的配置,保证链路信息的传递。

  • propagators 用于配置跟踪信息在上下文的传递方式。
  • sampler 采样器
  • env[language].env 添加到容器的环境变量

针对 Java 应用,通过环境变量 OTEL_EXPORTER_OTLP_ENDPOINT 设置 oltp 的端点,以及 OTEL_LOGS_EXPORTER 设置应用 日志的输出方式 oltp。也可以设置为 logging、oltp,将日志输出到控制台以及 oltp 端点。

kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: instrumentation-sample
spec:
  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: otlp
EOF

配置 OpenTelemetry Collector

在我们的设计用,Otel Collector 会将日志输出到 Loki,实际上是通过 Loki 的 HTTP API 来发送日志,因此需要使用适配 Loki API 的 exporterlokiexporter

lokiexporter 来自 Otel Collector 的 Contrib 库,并不在官方的 release 中。要想在 collector 中使用 lokiexporter 有两种方式:

Otel 收集器的详细配置可以参考 官方文档

  • 接收器(receiver),我们配置 otlp 来接收来自应用程序的跟踪信息。
  • 处理器(processor),将日志中的部分资源属性作为 loki 的标签,比如服务名、容器名、命名空间、pod 名。
  • 输出器(exporter),配置 Loki 的 HTTP API 端点 http://loki.default:3100/loki/api/v1/push
  • 管道服务(pipeline service),使用 otlp 作为输入源,将 loki 作为输出目的地。
kubectl apply -f - <<EOF
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: otel
spec:
  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
@RestController
public 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-weblombok

	<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 - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-sample
spec:
  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: 8080
EOF

应用部署完成后,通过端口转发可以成功访问应用。

curl localhost:8080
Hello World

测试

Grafana 配置完 Loki 的数据源之后,在 Explore 中选择配置的 Loki 数据源,然后在下方的 Label Filters 中选择过滤器名 service_name 和值 java-sample

点击 Run query 后可以看到搜索结果。

总结

在本文中,我们探讨了如何利用 OpenTelemetry 的自动检测功能来高效采集应用日志,通过 OpenTelemetry Collector 进行处理,并利用 Loki Exporter 将日志数据发送到 Loki。最后,我们展示了如何使用 Grafana 对这些日志进行深入的查询和分析。这一过程不仅优化了日志管理流程,还提升了数据的可视化和可用性。这种集成为开发者和运维团队提供了一个全面的视角,帮助他们更有效地理解和优化他们的应用和基础设施。特别是,如果将分布式跟踪的 traceid、spanid 等信息作为 Loki 日志的标签,将极大地增强了日志数据的可追踪性和可分析性。

关注"云原生指北"微信公众号 (转载本站文章请注明作者和出处乱世浮生,请勿用于任何商业用途)

标签:kubectl,Otel,Grafana,OpenTelemetry,Loki,日志
From: https://blog.51cto.com/addozhang/8965925

相关文章

  • 使用 OpenTelemetry 和 Loki 实现高效的应用日志采集和分析
    在之前的文章陆续介绍了如何在Kubernetes中使用Otel的自动插桩以及Otel与服务网格协同实现分布式跟踪,这两篇的文章都将目标聚焦在分布式跟踪中,而作为可观测性三大支柱之一的日志也是我们经常使用的系统观测手段,今天这篇文章就来体验下应用日志的操作闭环。背景OpenTel......
  • 第81讲:清理MySQL Binlog二进制日志的方式
    1.清理Binlog二进制日志的依据Binlog日志非常重要,但是占用的磁盘空间也很大,我们也需要定期的去清理二进制日志,在MySQL数据库中,提供了自动清理Binlog日志的参数,根据指定的天数,保留n天内的Binlog日志,也可以手动人为删除。在手动删除Binlog日志时,要切记不要使用rm-rf直接删除Binlog......
  • 【Python常用模块之logging模块】---日志输出功能(示例代码)
    title:【Python常用模块之logging模块】---日志输出功能(示例代码)date:2023-12-2420:14:06updated:2023-12-2420:23:00description:【Python常用模块之logging模块】---日志输出功能(示例代码)cover:https://pythonjishu.com/tdcgatffvrvdoop/2023年6月......
  • 微信小程序开发学习日志
    文件夹:pages:index:首页logs:日志json配置文件:app.json:app.json为全局配置,包括了所有页面路径(pages)、窗口外观(window)、界面表现(style)、底部tab等。#页面配置会覆盖全局配置project.config.json:"setting": 本地设置"es6": JS编译成ES5是否开启"postcss": 上传代码时样......
  • MySQL日志如何查询
    MySQL有多种类型的日志,包括错误日志、查询日志、慢查询日志等。以下是查询MySQL不同类型日志的方法:1.错误日志查询:MySQL错误日志记录了MySQL服务器启动、运行过程中的错误信息。错误日志通常位于MySQL数据目录下的错误日志文件中,文件名可能是error.log或hostname.err。......
  • JVM虚拟机系统性学习-JVM调优之通过gceasy分析GC日志对堆、元空间、线程堆栈和垃圾回
    通过gceasy工具对生成的GC日志进行分析这里使用的JDK版本为JDK8!在分析GC日志时,可以同时采用多种工具(Arthas、gceasy、JVM连接Graphana监控)进行分析,避免某种工具分析不准确gceasy每个月只可以免费分析5个gc日志,因此要节约机会!hhh!我们先将gc.log文件放入gceasy......
  • JVM虚拟机系统性学习-JVM调优之GC日志分析
    JVM调优首先,为什么要JVM调优呢?JVM调优的目的就是为了让应用程序使用最小的硬件消耗来承载更大的吞吐量什么情况下需要JVM调优呢?系统吞吐量下降,或系统延迟较高出现OOMFullGC频繁GC停顿时间过长(超过1s,已经影响用户体验)调优主要调什么?JVM调优主要是两方面:内存分配和垃圾回......
  • 客服端日志设计-iOS
    客户端日志系统使用场景用户通过appstore下载app后,在使用过程中出现了异常情况,例如功能异常等.例如BugHD会自动捕获崩溃信息,但开发人员想重现是不容易的.设计方案一.收集log模块化,暴露接口,对日志分级,info,debug(支持打印类似NSLog),warn,error等......
  • 补题日志
    补题日志**Codeforcesrating:1770**goal:1900ATcoderrating:1254goal:1600CodeforcesRound915(Div.2)D不难发现,设当前排列为\(q_1,q_2\dotsq_n\),把\(q_1\)移到末尾,造成的影响有:对于前缀中\(\text{mex}_i<q_1\)的\(i\),移动后不改变它的值。对于前......
  • CentOS7开启Firewalld防火墙日志记录获取被拦截的IP
    问题场景:在实际生产环境时使用该方法进行ES数据库白名单访问控制,但遇到业务侧反馈无法访问到ES数据库端口,需要加入到白名单,但业务侧用的IP业务侧无法准确给出于是通过如下面的方法解决这个问题1、firewalld的默认配置是不记录日志firewall-cmd--get-log-denied可以看到默认是off......