Exemplar 是用一个特定的 trace,代表在给定时间间隔内的度量。Metrics 擅长给你一个系统的综合视图,而 traces 给你一个单一请求的细粒度视图;Exemplar 是连接这两者的一种方式。
假设你的公司网站正经历着流量的激增。虽然超过百分之八十的用户能够在两秒内访问网站,但有些用户的响应时间超过了正常水平,导致用户体验不佳。
为了确定造成延迟的因素,你必须将快速响应的 trace 与缓慢响应的 trace 进行比较。鉴于典型生产环境中的大量数据,这将是非常费力和耗时的工作。
使用 Exemplar 来帮助隔离你的数据分布中的问题,方法是在一个时间间隔内找出表现出高延迟的查询痕迹。一旦你把延迟问题定位到几个示范跟踪,你就可以把它与其他基于系统的信息或位置属性结合起来,更快地进行根本原因分析,从而快速解决性能问题。
对 Exemplar 的支持仅适用于 Prometheus数据源。一旦你启用该功能,Exemplar 数据默认是可用的。
Grafana 在 "Explore" 视图和仪表盘中与指标一起显示 Exemplar 。每个 Exemplar 显示为高亮的星星。你可以将光标悬停在 Exemplar 上,查看唯一的 traceID,它是一个键值对的组合。要进一步分析,请点击 "traceID "属性旁边的蓝色按钮。示例如下:

Exemplars 是最近可观察性领域的一个热门话题,这是有原因的。
与 Prometheus 如何在 2012 年开始破而后立了大规模存储指标的成本结构,并在 2015 年真正实现,以及 Grafana Loki 如何在 2018 年破而后立了大规模存储日志的成本结构类似,Exemplar 也在对 trace 做同样的事情。为了了解原因,让我们看看云原生生态系统中可观察性的历史,以及 Exemplar 能够实现哪些优化。
核心是,Exemplar 是一种通过 ID 从有意义的指标和日志跳到追踪的方式。Grafana Tempo,Grafana Labs 的 开源、大规模分布式跟踪后端,就是围绕这个想法建立的,因为 Exemplar 使分布式跟踪的成本和性能特征变得好了。理想情况下,你永远不需要对你的追踪进行采样,而 Tempo 让这成为现实。
暂时忽略 Prometheus 出色的可扩展性、压缩性和性能,让我们把注意力放在标签集上。它们是关于你的时间序列的元数据。是什么集群、什么服务、哪个客户、什么部署级别等等都可以用非层次的键值对来编码。如果你正在读这篇文章,我很可能不需要说服你这个行业的变化有多大的颠覆性、影响力和持久性;我只是想提醒你,因为它与文本的其余部分有关。
这在几年前是革命性的:
acme_http_router_request_seconds_sum{path="/api/v1",method="GET"} 9036.32
acme_http_router_request_seconds_count{path="/api/v1",method="GET"} 807283.0
acme_http_router_request_seconds_sum{path="/api/v2",method="POST"} 479.3
acme_http_router_request_seconds_count{path="/api/v2",method="POST"} 34.0
早在 2015-2016 年,相关开发者就计划同样的标签集也应用于日志和追踪。这就是为什么 OpenMetrics 自 2017 年以来一直处在一个叫做 OpenObservability 的 GitHub 组织中,而不是 "仅仅 "一个叫做 OpenMetrics 的组织。
有了 Loki,这个梦想在 2018 年实现了。在你的指标和日志之间无缝移动,没有问题。这就是 "Like Prometheus but for logs"的标语的由来。
这让我们不得不将标签集应用于 trace,对吗?
2017 年,OpenMetrics 和 OpenCensus 开会,试图看看这两个项目是否可以合并。虽然由于设计目标、运营模式和数据模型的不兼容而没有成功,但这次会议还是改变了 OpenMetrics 和 Prometheus 的命运,也是引出了 Grafana Tempo 的核心设计。
本质上,Exemplar 就是以下三个想法:
通过 exemplars 将 trace ID 附加到指标上是非常简单的。在你的度量值(可能还有时间戳)后面加一个 "#",表示有一个 exemplars 存在,然后添加你的数据。
借用 OpenMetrics 规范 中的例子:
# TYPE foo histogram
foo_bucket{le="0.01"} 0
foo_bucket{le="0.1"} 8 # {} 0.054
foo_bucket{le="1"} 11 # {trace_id="KOO5S4vxi0o"} 0.67
foo_bucket{le="10"} 17 # {trace_id="oHg5SJYRHA0"} 9.8 1520879607.789
foo_bucket{le="+Inf"} 17
foo_count 17
foo_sum 324789.3
foo_created 1520430000.123
如果trace_id标签的名称和值让你想起 W3C 分布式跟踪工作组 提出的规范,那就不是巧合了。我们特意采纳了 W3C 的规范,同时没有强制要求它。这使我们能够在现有的规范工作的基础上,同时在分布式跟踪领域稳定下来之前不把 OpenMetrics 捆绑起来。
让我们看看里面的实际范例:
显示延迟小于 1 秒的直方图桶有一个运行时间为 0.67 秒、ID 为KOO5S4vxi0o的 trace。
显示 10 秒以下延迟的直方图桶有一个运行时间为 9.8 秒的 trace,时间为1520879607.789,ID 为oHg5SJYRHA0。
就是这样!
索引是昂贵的。把完整的上下文和元数据放在 trace 上意味着你需要通过它们来搜索 trace,这就意味着对它们进行索引。但是你想在你的指标、日志和 trace(以及 conprof、crashdumps 等)上有相同的标签。但是,由于你在其他数据上已经有了这些元数据,重用相同的索引以节省成本和时间如何?
通过在一个特定的时间点上将 trace 附在一个特定的时间序列或日志上,你就可以做到这一点。对于 trace 本身,你只需对 ID 进行索引,就可以了。
自动跟踪分析是一个广泛的领域;大量精湛的工程力量被用于使这个干草堆可被搜索。
如果有一个更便宜、更有效的方法呢?
日志已经可以告诉你一个错误状态或类似的情况。你不需要分析 trace 来找到那个错误。
指标中的计数器、直方图等已经是一种高度浓缩和优化的数据形式,被提炼成在这种情况下重要的东西。你不需要分析所有的 trace 来找到那个显示高延迟的 trace。
你的日志和你的指标已经告诉你为什么一个 trace 是需要深入调查的。你的标签给了你如何和在哪里产生 trace 的背景。在跳入 trace 的时候,你已经知道你在寻找什么和为什么。这就大大加快了发现的速度。
?️ Reference:
Exemplars storage | Prometheus Doc
--enable-feature=exemplar-storage
OpenMetrics 介绍了刮削目标为某些度量标准添加 Exemplars 的能力。典型应用场景是对 MetricSet 之外的数据的引用。一个常见的用例是 trace ID。
Exemplar 存储是作为一个固定大小的圆形缓冲区实现的,它将所有系列的 exemplar 存储在内存中。启用此功能将使 Prometheus 刮削来的 exemplar 的存储成为可能。配置文件块 storage/exemplars 可以用来控制循环缓冲区的大小。一个只有traceID=<jaeger-trace-id>的 exemplar 通过内存中的 exemplar 存储大约使用 100 字节的内存。如果 exemplar 存储被启用,我们也会将 exemplar 追加到 WAL 中进行本地持久化(在 WAL 持续时间内)。
?️ Reference:
有关 Exemplar 配置和如何启用 Exemplar 的更多信息,请参阅 在 Prometheus 数据源中配置 Exemplar
? Notes:
该功能在 Prometheus 2.26+ 和 Grafana 7.4+ 上可用。
Grafana 7.4 及以后的版本能够在 Explore 和仪表盘中显示与指标相关的 Exemplar 数据。Exemplar 数据是一种将特定事件中的高权重元数据与传统时间序列数据联系起来的方式。
通过添加外部或内部链接,在数据源设置中配置 Exemplars。

?️ Reference:
请参考 查看 exemplar 数据, 了解如何从指标和日志中钻取和查看 Exemplar trace 细节。
当 prometheus 数据源启用对 exemplar 支持时,你可以在 Explore 视图或从 Loki 日志细节中查看 exemplar 数据。
Explore 将 exemplar 的跟踪数据可视化为高亮的星星和指标数据。关于 Explore 如何将跟踪数据可视化的更多信息,请参考 Explore 中的跟踪。
要检查 exemplar 跟踪的细节。
将你的光标放在一个 exemplar (突出显示的星星)上。根据你的后端 trace 数据源,你会看到一个蓝色的按钮,标签是 Query with <DataSource Name>。在下面的例子中,Trace 的数据源是 Tempo。

点击 traceID 属性旁边的 Query with Tempo 选项。Trace 的细节,包括 trace 中的 span 都列在右边的独立面板中。

你也可以在 Explore 中查看 Loki 日志中的 exemplar 跟踪细节。在 Loki 的 Derived fields 链接中使用 regex 来提取 traceID 信息。现在当你展开 Loki 日志时,你可以在检测字段部分看到 traceID 属性。要了解更多关于如何将日志信息的一部分提取到内部或外部链接中,请参考 在 Loki 中使用衍生字段。
要查看 exemplar 跟踪的细节:
展开一个日志行,向下滚动到 "检测到的字段 "部分。根据你的后端跟踪数据源,你会看到一个蓝色的按钮,标签是<数据源名称>。
点击traceID属性旁边的蓝色按钮。通常情况下,它将有后端数据源的名称。在下面的例子中,追踪的数据源是 Tempo。追踪的细节,包括追踪中的 span 都列在右边的独立面板中。

Exemplars 就是这样的。工程设计始终是为了适应设计目标和约束条件而进行的权衡。
Prometheus 将整个行业转移到一套新的权衡标准,创造了云原生观察能力的基石。Grafana Loki 也在做同样的日志工作。Grafana Tempo 正在通过 exemplars 的力量为分布式追踪做这件事。
Tempo 的工作是存储大量的跟踪,把它们放在对象存储中,并通过 ID 来检索它们。由于所有这些都遵循一个整体设计,在指标、日志和追踪之间的无缝移动已经成为可能,而且是真正的云原生规模。


Exemplars 已经 从 7.4 开始在 Grafana 中得到支持。
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,
在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList()Obt
基础版云数据库RDS的产品系列包括基础版、高可用版、集群版、三节点企业版,本文介绍基础版实例的相关信息。RDS基础版实例也称为单机版实例,只有单个数据库节点,计算与存储分离,性价比超高。说明RDS基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于
我使用irb。下面是我写的代码。“斧头”..“bc”我期待"ax""ay""az""ba"bb""bc"但结果只是“斧头”..“bc”我该如何纠正?谢谢。 最佳答案 >puts("ax".."bc").to_aaxayazbabbbc 关于ruby-从结束值创建一系列字符串,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7617092/
使用RubyonRails,我使用给定的增量(例如每30分钟)用时间填充“选择”。目前我正在YAML文件中写出所有的可能性,但我觉得有一种更巧妙的方法。我想我想提供一个开始时间、一个结束时间、一个增量,并且目前只提供一个名为“关闭”的选项(想想“business_hours”)。所以,我的选择可能会显示:'Closed'5:00am5:30am6:00am...[allthewayto]...11:30pm谁能想出更好的方法,或者只是将它们全部“拼写”出来的最佳方法? 最佳答案 此答案基于@emh的答案。defcreate_hour
我为你们准备了一个简单的。我想要一个特色内容部分,其中排除了当前文章所以这可以通过delete_if使用MiddlemanBlog:但是我使用的是中间人代理,所以我无法访问current_article方法...我有一个YAML结构,其中包含以下模拟数据(以及其他数据),文件夹设置如下:data>site>caseStudy>RANDOM-ID423536.yaml(由CMS生成)在每个yaml文件中,您会发现如下内容::id:2k1YccJrQsKE2siSO6o6ac:title:Heyplace我的config.rb看起来像这样data.site.caseStudy.eachdo
有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N
我正在为我的网站使用MiddlemanBloggem,但默认情况下,博客文章似乎需要位于/source中,这在查看vim中的树时并不是特别好并尝试在其中找到其他文件之一(例如模板)。通过查看文档,我看不出是否有任何方法可以移动博客文章,以便将它们存储在其他地方,例如blog_articles文件夹或类似文件夹。这可能吗? 最佳答案 将以下内容放入您的config.rb文件中。activate:blogdo|blog|blog.permalink=":year-:month-:day-:title.html"blog.sources=
所以我正在关注http://guides.rubyonrails.org/getting_started.html上的官方ROR教程我被困在第5.8节,它教我如何列出所有文章下面是我的controller和index.html.erbControllerclassArticlesControllerindex.html.erbListingarticlesTitleText我收到带有错误消息的NoMethodErrorinArticles#indexundefinedmethod`each'fornil:NilClass"怎么了?我从网站上复制并粘贴了代码以查看我做错了什么,但仍然无法