jjzjj

Grafana 系列文章(二):使用 Grafana Agent 和 Grafana Tempo 进行 Tracing

east4ming 2023-03-28 原文

?️URL: https://grafana.com/blog/2020/11/17/tracing-with-the-grafana-cloud-agent-and-grafana-tempo/

✍Author: Robert Fratto • 17 Nov 2020

?Description:

Here's your starter guide to configuring the Grafana Agent to collect traces and ship them to Tempo, our new distributed tracing system.

编者注:代码片段已于 2021-06-23 更新。

早在 3 月份,我们 介绍 了 Grafana Agent,这是 Prometheus 的一个子集,为托管指标而建。它使用了很多与 Prometheus 相同的经过实战检验的代码,可以节省 40%的内存使用。

自推出以来,我们一直在为 Agent 添加功能。现在,新增功能有:集群机制,额外的 Prometheus exporters,以及对 Loki 的支持。

我们的最新功能。Grafana Tempo! 这是一个易于操作、规模大、成本低的分布式追踪系统。

在这篇文章中,我们将探讨如何配置 Agent 来收集跟踪,并将其发送到 Tempo

配置 Tempo 支持

在你现有的 Agent 配置文件中添加 trace 支持很简单。你所需要做的就是添加一个tempo 块。熟悉 OpenTelemetry Collector 的人可能会认出以下代码块中的一些设置。

# other Agent settings
tempo:
  configs:
  - name: default
    receivers:
      jaeger:
        protocols:
          thrift_compact:
    attributes:
      actions:
        - action: upsert
            key: env
            value: prod
    remote_write:
     - endpoint: tempo-us-central1.grafana.net:443
       basic_auth:
         username: 12345
         # Replace <Grafana API Key> below with an API key that
         # has the "Metrics Publisher" role
         password: <Grafana API Key>

接收器允许 Grafana Agent 接受来自众多系统的追踪数据。我们目前支持从 JaegerKafkaOpenCensusOTLPZipkin 接收跨度。

虽然 OpenTelemetry Collector 允许你配置指标和日志接收器,但我们目前只公开了与追踪有关的接收器。我们相信 Agent 内现有的 Prometheus 和 Loki 支持将满足其他支柱观察能力的需要。

如果你愿意,你可以将代理配置为接受每一个接收器的数据。

tempo:
  # 键,配置启用一个接收器或其协议。
  # 把它设置为空值可以启用该接收器或协议的默认配置。
  receivers:
    # 支持 grpc14250 端口的 spans,
    # 6832 端口的 thrift_binary,
    # 6831 端口的 thrift_compact,
    # 以及 14268 端口的 thrift_http。
    # 具体的端口号可以 特定的端口号可以在协议的配置中自定义。
    jaeger:
      protocols:
        grpc:
        thrift_binary:
        thrift_compact:
        thrift_http:
    # 配置 opencensus 支持。span 可以通过端口 55678 发送,
    # 这是默认的。
    opencensus:
    # 配置 otlp 支持。Spans 可以被发送到 55680 端口,
    # 这是默认的。
    otlp:
      protocols:
        grpc:
        http:
    # 配置 zipkin 支持。Spans 可以被发送到 9411 端口,
    # 这是默认的。
    zipkin:

另一方面,属性使操作者能够操作发送到 Grafana Agent 的传入 span 上的标签。当你想添加一组固定的元数据时,这真的很有用,比如备注一个环境。

attributes:
  actions:
  - action: upsert
    key: env
    value: prod

上面的配置例子为所有收到的 span 设置了一个 env标签,其值为produpsert动作意味着具有现有 env标签的span将被覆盖。这对于保证你知道哪个 Agent 收到了 span 以及它在哪个环境下运行是很有用的。

属性 (Attributes ) 真的很强大,并且支持超出这里的例子的使用情况。请查看 OpenTelemetry 关于它们的文档 以了解更多信息。

但在 Grafana Labs,我们并没有仅仅使用 OpenTelemetry Collector 的一个子集就了事;我们增加了对 Prometheus 风格的scrape_configs的支持,可以用来根据发现目标的元数据自动标记传入的 span。

用 Prometheus 服务发现附加元数据

Promtail 是一个日志客户端,用于收集日志并将其发送到 Loki。它最强大的功能之一是支持使用 Prometheus 的服务发现机制。这些服务发现机制使你能够将相同的元数据附加到你的日志和你的指标上。

当你的指标和日志有相同的元数据时,你就可以降低在系统之间切换的认知开销,并且让有一种你的所有数据都储存在一个系统中的 "感觉"。我们希望这种能力也能扩展到追踪方面。

Joe Elliott 在 Agent 的追踪子系统中增加了相同的 Prometheus 服务发现机制。它的工作原理是将发送 span 的系统的 IP 地址与发现的服务发现目标的地址相匹配。

对于 Kubernetes 用户来说,这意味着你可以动态地附加发送 span 的容器的命名空间、pod 和 container 名称的元数据。

tempo:
  configs:
  - name: default
    receivers:
    jaeger:
        protocols:
        thrift_compact:
    scrape_configs:
    - bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
    job_name: kubernetes-pods
    kubernetes_sd_configs:
    - role: pod
    relabel_configs:
    - source_labels: [__meta_kubernetes_namespace]
      target_label: namespace
    - source_labels: [__meta_kubernetes_pod_name]
      target_label: pod
    - source_labels: [__meta_kubernetes_pod_container_name]
      target_label: container
    tls_config:
      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      insecure_skip_verify: false
    # remote_write, etc

不过,这个功能不仅仅对 Kubernetes 用户有用。这里支持 Prometheus 的所有 各种服务发现机制。这意味着你可以在你的度量、日志和追踪之间使用相同的scrape_configs来获得相同的标签集,当从你的度量、日志和追踪中切换时,可以轻松地在你的可观察性数据之间转换。

配置 Span 的推送方式

当然,仅仅收集 span 并不十分有用!配置 Tempo 支持的最后部分是通过remote_write部分。remote_write描述了一个类似于 Prometheus 的配置块,用来控制收集的 span 被发送到哪里。

对于好奇的人来说,这是对 OpenTelemetry Collector 的 OTLP exporter 的一个封装。由于 Agent 导出 OTLP 格式的 span,这意味着你可以将 span 发送到任何支持 OTLP 数据的系统。我们今天的重点是 Tempo,但你甚至可以让 Agent 发送跨度到另一个 OpenTelemetry 采集器。

除了端点和认证,remote_write允许你控制 span 的排队和重试功能。批处理 (Batching)是在remote_write之外管理的,可以更好地压缩 span,减少用于向 Tempo 传输数据的出站连接数。和前面一样,OpenTelemetry 在这方面有一些 相当好的文档

tempo:
  configs:
  - name: default
    # span 的批处理设置。在收集 10,000 个跨度后
    # 或 10s 后(以先到者为准)完成一个批次。
    batch:
      send_batch_size: 10000
      timeout: 10s
    # remote_write, etc

remote_write方面,queuesretries允许你配置在内存中保留多少个批次,以及如果一个批次碰巧失败了,你将重试多长时间。这些设置与 OpenTelemetry's OTLP exporterretry_on_failuresending_queue设置相同。

tempo:
  configs:
  - name: default
    remote_write:
    - endpoint: tempo-us-central1.grafana.net:443
      basic_auth:
        username: 12345
        password: api_key
      # 将默认的队列大小增加一倍,以便在内存中保留更多的批次,
      # 但在 5 秒后放弃重试失败的 span。
      sending_queue:
        queue_size: 10000
      retry_on_failure:
        max_elapsed_time: 5s

虽然把最大重试时间设置得很高很诱人,但它很快就会变得很危险。重试会增加从 Agent 到 Tempo 的网络流量总量,与其不断重试,不如放弃 span 。另一个风险是内存的使用。如果你的后端发生故障,高重试时间将迅速填满 span 队列,并可能以 Out Of Memory 错误使 Agent 宕机。

因为对于一个有大量 span 吞吐量的系统来说,100%的 span 被存储是不现实的,控制批处理、队列和重试逻辑以满足你的特定网络使用,对于有效追踪是至关重要的。

下回见

我们已经谈到了如何手动配置 Grafana Agent 以获得 tracing 支持,但要想了解一个实际的例子,请查看 production-ready tracing Kubernetes manifest。这个清单附带的配置涉及到这里的所有内容,包括服务发现机制,以自动将 Kubernetes 元数据附加到传入的 span 上。

我非常感谢 Joe 从他繁忙的 Tempo 工作中抽出时间,在 Agent 中添加跟踪支持。我很高兴 Grafana Agent 现在支持大部分的 Grafana 堆栈,而且我对接下来的产品更感兴趣

原文内置:

开始使用 Tempo 的最简单方法是在 Grafana Cloud。我们有免费的(包括 50GB 的痕迹)和付费的 Grafana Cloud 计划,以满足各种使用情况 - 现在注册免费

词汇表

英文 中文 备注
Receivers 接收器 Grafana Agent 组件
Trace 追踪
span 跨度 Tracing 专有名词

Grafana 系列文章

Grafana 系列文章

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

有关Grafana 系列文章(二):使用 Grafana Agent 和 Grafana Tempo 进行 Tracing的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  10. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

随机推荐