使用 OpenTelemetry 定制跨度名称并丰富跨度而无需更改代码 – 第 1 部分

2024年11月6日   |   by mebius

作者:来自 ElasticDavid Hope

%title插图%num

OpenTelemetry Collector 提供强大的功能,可以在遥测数据到达可观察性工具之前丰富和细化遥测数据。在这篇博文中,我们将探讨如何利用 Collector 在 Elastic Observability 中创建更有意义的 transaction 名称,从而显著提高监控数据的价值。

OpenTelemetry Collector 提供强大的功能,可以在遥测数据到达可观察性工具之前对其进行丰富和细化。在这篇博文中,我们将探讨如何利用 Collector 在 Elastic Observability 中创建更有意义的事务名称,从而显著提高监控数据的价值。

考虑以下场景:你有一个事务被简单地标记为 “HTTP GET”,平均响应时间为 5 毫秒。但是,这个通用标签掩盖了各种不同的操作 – 付款处理、用户登录和将商品添加到购物车。5 毫秒的平均值是否真正代表了这些不同操作的性能?显然不是。

发生的另一个问题是跨度跟踪变得完全混杂,因此登录跨度和图像服务跨度都成为同一存储桶的一部分,这使得在 Elastic 中进行延迟相关性分析等工作变得困难。

我们将重点介绍一种使用收集器(collector)属性的特定技术,并转换处理器以从 HTTP URL 中提取有意义的信息并使用它来创建更具描述性的跨度名称。这种方法不仅可以提高指标的准确性,还可以增强你快速识别和排除微服务架构中性能问题的能力。

通过结合使用这些处理器,我们可以快速解决过于通用的事务名称问题,创建更精细、更翔实的标识符,从而准确了解服务的性能。

但是,谨慎使用这种技术至关重要。虽然更详细的事务名称可以显著提高可观察性,但也可能导致意想不到的挑战:基数爆炸。在深入研究实施细节时,我们还将讨论如何在粒度和可管理性之间取得适当的平衡,确保我们的解决方案能够增强而不是压倒我们的可观察性堆栈。

在以下部分中,我们将逐步介绍配置,解释每个处理器如何为我们的目标做出贡献,并重点介绍避免基数问题等潜在陷阱的最佳实践。无论你是 OpenTelemetry 的新手还是希望优化现有设置,本指南都将帮助你从遥测数据中获取更有意义的见解。

有关 OpenTelemetry 的更多描述,请参阅文章 “将 Logstash 管道转换为 OpenTelemetry Collector 管道”。

先决条件和配置

如果你打算关注此博客,以下是我们用于设置配置的一些组件和详细信息:

  • 确保你在 Elastic Cloud 上有一个帐户和一个已部署的堆栈(请参阅此处的说明)。
  • 我也在我的环境中使用 OpenTelemetry 演示,这一点很重要,因为这个演示有我想要解决的特定问题。你应该克隆存储库并按照此处的说明进行操作。我建议使用 Kubernetes,我将在我的 AWS EKS(Elastic Kubernetes Service)环境中执行此操作。

OpenTelemetry 演示

OpenTelemetry 演示是一个全面的、基于微服务的应用程序,旨在展示 OpenTelemetry 仪表的功能和最佳实践。它模拟了一个电子商务平台,结合了各种服务,例如前端、购物车、结帐和付款处理。对于希望采用 OpenTelemetry 的开发人员和组织来说,此演示是一个出色的学习工具和参考实现。

该演示应用程序在其互连服务中生成追踪、指标和日志,展示了 OpenTelemetry 如何深入洞察复杂的分布式系统。它特别适合用于尝试不同的采集、处理和可视化技术,是探索可观测性概念和工具(如 OpenTelemetry Collector)的理想实践平台。

通过使用真实场景和常见的架构模式,OpenTelemetry Demo 帮助用户理解如何在自己的应用中有效实现可观测性,以及如何利用这些数据进行性能优化和故障排查。

拥有 Elastic Cloud 实例并启动 OpenTelemetry 演示后,你应该在 Elastic Service Map 页面上看到类似以下内容:

%title插图%num

导航到跟踪页面将为你提供以下设置。

%title插图%num

如你所见,这里有一些非常广泛的事务名称,如 HTTP GET,并且对于服务中的特定业务功能,平均值不会非常准确,如图所示。

%title插图%num

因此让我们使用 OpenTelemetry Collector 来解决这个问题。

OpenTelemetry Collector

OpenTelemetry Collector 是 OpenTelemetry 生态系统中的一个重要组件,它是一种与供应商无关的接收、处理和导出遥测数据的方式。它充当集中式可观察性管道,可以从各种来源收集跟踪、指标和日志,然后将这些数据转换并路由到多个后端系统。

收集器的灵活架构允许通过各种接收器、处理器和导出器轻松配置和扩展,你可以在此处进行探索。我个人发现,浏览 “contrib” 档案对于找到我不知道存在的技术非常有用。这使得 OpenTelemetry Collector 成为希望标准化其可观察性数据管道、减少开销并与不同监控和分析平台无缝集成的组织的宝贵工具。

让我们回到我们的问题,我们如何将 Elastic 使用的事务名称更改为更有用的名称,以便我们的 HTTP GET 转换为类似 payment-service/login 的名称?我们要做的第一件事是获取完整的 http url,并考虑其中哪些部分与我们的交易相关。查看 span 详细信息,我们会看到一个 url

my-otel-demo-frontendproxy:8080/api/recommendations?productIds=&sessionId=45a9f3a4-39d8-47ed-bf16-01e6e81c80bc&currencyCode=

%title插图%num

现在,显然我们不想创建映射到每个会话 ID 的事务名称,这会导致我们之前讨论过的基数爆炸,但是,像 URL ‘api/recommendations’ 的前两个部分看起来正是我们需要的那种东西。

属性处理器 – attribute processor

OpenTelemetry 收集器在这里为我们提供了一个有用的工具,属性处理器可以帮助tgcode我们提取 URL 的各个部分,以便稍后在我们的可观察性管道中使用。要做到这一点非常简单,我们只需构建一tgcode个如下所示的正则表达式。现在我应该提到,我自己没有生成这个正则表达式,但我使用 LLM 为我做了这件事,再也不用担心正则表达式了!

attributes:
  actions:
    - key: http.url
      action: extract
      pattern: '^(?Phttps?://[^/]+(?:/[^/]+)*)(?:/(?P[^/?]+/[^/?]+))(?:?|/?$)'

此配置为我们做了一些繁重的工作,因此让我们分解一下:

  • 我们使用属性处理器,它非常适合处理跨度属性。
  • 我们的目标是传入跨度的 http.url 属性。
  • 提取操作告诉处理器使用我们的正则表达式模式提取 URL 的特定部分。

现在,关于该正则表达式 – 它旨在提取两个关键信息:

  • short_url:这将捕获协议、域以及可选的第一个路径段。例如,在 “https://example.com/api/users/profile” 中,它将抓取 “https://example.com/api”。
  • url_truncated_pa​​th:这将捕获接下来的两个路径段(如果存在)。在我们的示例中,它将提取 “users/profile”。

为什么这很有用?好吧,它允许我们根据 URL 结构创建更具体的事务名称,而无需包含可能导致基数爆炸的过于具体的细节。例如,我们避免捕获唯一 ID 或查询参数,因为这些参数会为每个请求创建新的 transaction 名称。

因此,如果我们有一个类似 “https://example.com/api/users/profile?id=123” 的 URL,我们提取的 url_truncated_pa​​th 将是 “users/profile”。这给了我们一个很好的平衡 – 它比 “HTTP GET” 更具体,但又不会太具体以至于我们最终得到数千个唯一的 transaction 名称。

现在值得一提的是,如果你没有要用于命名事务的属性,则值得查看 SDK 或代理的选项,例如,Java 自动检测 Otel 代理具有以下用于捕获请求和响应标头的选项。然后,如果 URL 不足,你可以随后使用此数据来命名你的事务!

在接下来的步骤中,我们将了解如何使用这些提取的信息来创建更有意义的跨度名称,从而为我们的可观察性数据提供更好的粒度,而不会使我们的系统不堪重负。请记住,我们的目标是提高我们的可见性,而不是淹没在过于具体的指标的海洋中!

将所有内容整合在一起

OpenTelemetry 收集器的最终配置如下,请记住,这将进入 opentelemetry-demo/kubernetes/elastic-helm/configmap-deployment.yaml 并使用 kubtgcodeectl apply -f configmap-deployment.yaml 应用

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: elastic-otelcol-agent
  namespace: default
  labels:
    app.kubernetes.io/name: otelcol

data:
  relay: |
    connectors:
      spanmetrics: {}
    exporters:
      debug: {}
      otlp/elastic:
        endpoint: ${env:ELASTIC_APM_ENDPOINT}
        compression: none
        headers:
          Authorization: Bearer ${ELASTIC_APM_SECRET_TOKEN}
    extensions:
    processors:
      batch: {}
      resource:
        attributes:
          - key: deployment.environment
            value: "opentelemetry-demo"
            action: upsert
      attributes:
        actions:
          - key: http.url
            action: extract
            pattern: '^(?Phttps?://[^/]+(?:/[^/]+)*)(?:/(?P[^/?]+/[^/?]+))(?:?|/?$)'
      transform:
        trace_statements:
          - context: span
            statements:
              - set(name, attributes["url_truncated_path"])
    receivers:
      httpcheck/frontendproxy:
        targets:
        - endpoint: http://example-frontendproxy:8080
      otlp:
        protocols:
          grpc:
            endpoint: ${env:MY_POD_IP}:4317
          http:
            cors:
              allowed_origins:
              - http://*
              - https://*
            endpoint: ${env:MY_POD_IP}:4318
    service:
      extensions:
      pipelines:
        logs:
          exporters:
          - debug
          - otlp/elastic
          processors:
          - batch
          - resource
          - attributes
          - transform
          receivers:
          - otlp
        metrics:
          exporters:
          - otlp/elastic
          - debug
          processors:
          - batch
          - resource
          receivers:
          - httpcheck/frontendproxy
          - otlp
          - spanmetrics
        traces:
          exporters:
          - otlp/elastic
          - debug
          - spanmetrics
          processors:
          - batch
          - resource
          - attributes
          - transform
          receivers:
          - otlp
      telemetry:
        metrics:
          address: ${env:MY_POD_IP}:8888

你会注意到,我们通过将丰富和转换添加到收集器配置底部管道中的跟踪部分,将所有内容联系在一起。这是我们可观察性管道的定义,将我们讨论过的所有部分整合在一起,以创建更有意义且可操作的遥测数据。

通过实施此配置,你将朝着更具洞察力的可观察性迈出重要一步。你不仅仅是在收集数据;你正在对其进行改进,以提供有关应用程序性能的清晰、可操作的见解,请查看下面的最终结果!

%title插图%num

准备好将你的可观察性提升到新的水平了吗?

使用 Elastic Observability 实施 OpenTelemetry 为理解和优化你的应用程序开辟了无限可能。但这仅仅是个开始!为了进一步增强你的可观察性之旅,请查看这些宝贵的资源:

我们鼓励你深入研究,尝试这些配置,看看它们如何转换你的可观察性数据。请记住,关键是在细节和可管理性之间找到适当的平衡。

你是否在你的可观测性管道中实施了类似的策略?我们非常乐意听到你的经验和见解!请在下方评论分享你的想法,或在我们的社区论坛上联系我们。

敬请期待本系列的第二部分,我们将探讨一种高级数据收集技术,该技术可帮助你通过 Java 插件在无需代码的情况下收集更细粒度的数据,包括 Span 名称、上下文信息和指标数据。

原文:Tailoring span names and enriching spans without changing code with OpenTelemetry – Part 1 — Elastic Observability Labs

文章来源于互联网:使用 OpenTelemetry 定制跨度名称并丰富跨度而无需更改代码 – 第 1 部分

相关推荐: 释放专利力量:Patently 如何利用向量搜索和 NLP 简化协作

作者:来自 ElasticMatt Scourfield, Andrew Crothers, Brian Lambert 组织依靠知识产权 (IP) 来推动创新、保持竞争优势并创造收入来源。对于希望将新产品推向市场的公司来说,弄清楚谁拥有哪些专利是一项必不可少…

Tags: , , ,