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

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

背景

OpenTelemetry 简介

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

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

Loki 简介

Loki 是 Grafana 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 的 exporter:lokiexporter。

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

  • 使用官方提供的工具 OpenTelemetry Collector Builder (ocb) 在构建 collector 的二进制时将 lokiexporter 加入其中。
  • 使用 官方提供的发行包 otelcol-contrib,这个包中包含了 Contrib 库所有的第三方组件。但不推荐在生产环境中使用,仅供测试。我们的演示中将会使用该发行包。

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 日志的标签,将极大地增强了日志数据的可追踪性和可分析性。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/269210.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springCould中的zookeeper-从小白开始【3】

目录 1.启动zookeeper❤️❤️❤️ 2.创建8004模块 ❤️❤️❤️ 3.临时节点还是永久节点❤️❤️❤️ 4.创建zk80消费模块❤️❤️❤️ 1.启动zookeeper❤️❤️❤️ 进入自己zookeeper的bin目录下 分别使用命令&#xff1a; ./zkServer.sh start 和 ./zkCli.sh -serve…

旅游品牌网站搭建的作用是什么

我国旅游业规模非常高&#xff0c;各地大小旅游景区也是非常多&#xff0c;尤其节假日更是可以达到峰值&#xff0c;无论周边游还是外地游对所要去的景区&#xff0c;消费者总是需要来回了解很多&#xff0c;浏览器查或旅行社咨询等。 对旅游企业而言&#xff0c;传统线下方式…

QT 构建项目报错Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7

问题 Getting NoClassDefFoundError: Could not initialize class org.codehaus.groovy.vmplugin.v7.Java7获取 NoClassDefFoundError&#xff1a;无法初始化类 org.codehaus.groovy.vmplugin.v7.Java7 解决方法一 java版本 过高 将java版本降低&#xff0c;例如从java17降…

虹科方案|车内智慧大脑:基于车载网络捕获的全景数据处理

导读&#xff1a;随着汽车电子技术的不断发展&#xff0c;车载网络已经成为汽车智能化和互联互通的关键组成部分。然而随着汽车系统的复杂性增加&#xff0c;CAN的带宽和数据处理能力已不足以满足快速增长的数据需求。为了应对这一挑战&#xff0c;虹科智能互联提出了基于车载网…

哪个超声波清洗机好?适合洗眼镜超声波清洗机有哪些?

随着科技的进步&#xff0c;超声波清洗机已经成为了家居清洁的必备神器。尤其是对于眼镜、珠宝、饰品等需要深度清洁的小物件&#xff0c;超声波清洗机更是不可或缺。眼镜店最经常看见超声波清洗机的身影&#xff0c;可以很好帮我们清洗眼镜同时有些比较好的超声波清洗机还会带…

Matplotlib ------ 纵坐标科学计数法含义

matplotlib 纵坐标科学计数法含义 引言正文 引言 今天画图时遇到了一个问题&#xff0c;发现纵坐标是科学计数法的表示&#xff0c;但是很难理解它的含义&#xff0c;这里特来记录一下。 正文 我们以下图为例&#xff0c; 由图上我们可以看出&#xff0c;纵坐标显示为 1e-…

高压放大器的考虑因素有哪些

高压放大器是一种重要的电子设备&#xff0c;用于放大高电压信号。其设计和应用需要考虑多种因素&#xff0c;以确保性能稳定、安全可靠。以下是设计高压放大器时需要考虑的主要因素&#xff1a; 电压范围需求&#xff1a;首要考虑是要放大的电压信号范围。高压放大器应能够处理…

SpringBoot的测试

&#x1f648;作者简介&#xff1a;练习时长两年半的Java up主 &#x1f649;个人主页&#xff1a;程序员老茶 &#x1f64a; ps:点赞&#x1f44d;是免费的&#xff0c;却可以让写博客的作者开心好久好久&#x1f60e; &#x1f4da;系列专栏&#xff1a;Java全栈&#xff0c;…

CentOS7部署bitbucket7.21.20-postgresql版

文章目录 1.资源下载2.上传服务器3.赋予执行权限并执行安装4.执行安装5.访问Bitbucket6.Bitbucket安装页面配置6.1连接Jira应用程序到PostgreSQL6.1.1创建并配置PostgreSQL数据库6.1.2测试数据库连接 6.2授权6.2.1授权包6.2.1.1资源地址6.2.1.2上传到服务器 6.2.2停止bitbucket…

PDF控件Spire.PDF for .NET【安全】演示:在 PDF 中添加或删除数字签名

随着 PDF 文档在商业中越来越流行&#xff0c;确保其真实性已成为一个关键问题。使用基于证书的签名对 PDF 进行签名可以保护内容&#xff0c;还可以让其他人知道谁签署或批准了该文档。在本文中&#xff0c;您将了解如何使用不可见或可见签名对 PDF 进行数字签名&#xff0c;以…

用CSDN训练的InsCode AI创作博文:数据治理体系建设

想不想用AI帮我们写方案&#xff1f; 想尝试用CSDN提供的InsCode AI创作助手协助我们进行技术方案的创作&#xff0c;看看效果如何&#xff0c;能不能辅助我们日常的方案编写与创作&#xff1f;以前用ChatGPT也尝试过&#xff0c;但对于专业性更强的内容&#xff0c;还有表现的…

VMware虚拟机安装Ubuntu系统教程

所使用的文件如下&#xff1a; VMware Workstation 17 Pro ubuntu-22.04.3-desktop-amd64.iso 一、ubuntu 命名规则及各版本一览表 1.ubuntu 命名规则&#xff1a; 例如&#xff1a;ubuntu 16.04 LTS 是长期维护版本&#xff1b;ubuntu 17.04 是新特性版本 前两位数字为发…

【Unity学习笔记】1.创建场景

创建场景 注1&#xff1a;samplescene&#xff08;示例场景&#xff09;、standard assets&#xff08;标准资产&#xff09;、favorites&#xff08;收藏夹&#xff09;、terrain&#xff08;地形&#xff09;。 注2&#xff1a;favorites用于存放各种资源&#xff1b;sample…

【小白专用】Apache下禁止显示网站目录结构的方法 更新23.12.25

给我一个网站地址&#xff0c;我点开后显示的是目录格式&#xff0c;把网站的目录结构全部显示出来了 这个显示结果不正确&#xff0c;不应该让用户看到我们的目录结构 配置文件的问题,apache配置文件里有一项可以禁止显示网站目录的配置项&#xff0c;禁止掉就好了 在apache…

基于ssm出租车管理系统的设计与实现论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本出租车管理系统就是在这样的大环境下诞生&#xff0c;其可以帮助管理者在短时间内处理完毕庞大的数据信息&…

做外贸其实也并没有那么容易

最近无意中看到一个视频&#xff0c;视频的内容是外贸博主和一个连线人的对话&#xff0c;连线人的诉求是如何做外贸&#xff1f;怎么能把外贸做好&#xff0c; 通过博主和这个人的沟通来看&#xff0c;这个连线的人他从来没有接触过外贸&#xff0c;也不愿意去别的外贸公司上…

图像ISP处理——畸变校正算法

图像畸变校正算法主要用于矫正图像中因为摄像机镜头畸变而引起的形状和尺寸变化。摄像机镜头畸变主要包括径向畸变和切向畸变。以下是一些常见的图像畸变校正算法&#xff1a; 多项式畸变校正法&#xff08;Polynomial Distortion Correction&#xff09;&#xff1a; 原理&am…

Java:LocalDate / LocalDateTime加减时间

在线API参考&#xff1a;LocalTime (Java Platform SE 8 ) 方法介绍 方法1方法1说明plusYears(long years) minusYears(long years) 返回增加/减少了年数的副本plusMonths(long months) minusMonths(long months)返回增加/减少了月数的副本plusWeeks(long weeks) minusWeeks(…

Wafer晶圆封装工艺介绍

芯片封装的目的&#xff08;The purpose of chip packaging&#xff09;: 芯片上的IC管芯被切割以进行管芯间连接&#xff0c;通过引线键合连接外部引脚&#xff0c;然后进行成型&#xff0c;以保护电子封装器件免受环境污染&#xff08;水分、温度、污染物等&#xff09;&…

Linux开发工具——gcc篇

gcc的使用 文章目录 gcc的使用 历史遗留问题&#xff08;普通用户sudo&#xff09; gcc编译过程 预处理&#xff08;进行宏替换&#xff09; 编译&#xff08;生成汇编&#xff09; 汇编&#xff08;生成机器可识别代码&#xff09; 链接&#xff08;生成可执行文件或库文件&a…