Grafana 是用于时序数据的事实上的仪表盘解决方案。它支持近百个数据源。
Grafana Labs 想从一个仪表盘解决方案转变成一个可观察性 (observability) 平台,成为你需要对系统进行调试时的首选之地。
可观察性。关于这意味着什么,有很多的定义。可观察性就是对你的系统以及它们的行为和表现的可见性。典型的是这种模式,即可观察性可以分成三个部分(或支柱):指标 (Metrics)、日志 (Logs) 和跟踪 (Traces);每个部分都相互补充,帮助你快速找出问题所在。
下面是在 Grafana Labs 博客和演讲中反复出现的一张图:

Slack 向我发出警告,说有问题,我就打开 Grafana 上服务的相关仪表盘。如果我发现某个面板或图表有异常,我会在 Prometheus 的用户界面中打开查询,进行更深入的研究。例如,如果我发现其中一个服务抛出了 500 个错误,我会尝试找出是否是某个特定的处理程序/路由抛出了这个错误,或者是否所有的实例都抛出了这个错误,等等。
接下来,一旦我有了一个模糊的心理模型,知道什么地方出了问题,我就会看一下日志(比如在 splunk 上)。在 Loki 之前,我习惯于使用 kubectl 来获取相关的日志,看看错误是什么,以及我是否可以做些什么。这对错误来说很有效,但有时我会因为高延迟而放弃。之后,我从 traces (比如 AppD) 中得到更多的信息,关于什么是慢的,哪个方法/操作/功能是慢的。或者使用 Jaeger 来获得追踪信息。
虽然它们并不总是直接告诉我哪里出了问题,但它们通常让我足够近距离地查看代码并找出哪里出了问题。然后,我可以扩展服务(如果服务超载)或部署修复。
Prometheus 工作得很好,Jaeger 也渐入佳境,而 kubectl 也很不错。标签 (label) 模型很强大,足以让我找到出错服务的根源。如果我发现 ingester 服务在出错,我会做:kubectl --namespace prod logs -l name=ingester | grep XXX,以获得相关的日志,并通过它们进行 grep。
如果我发现某个特定的实例出错了,或者我想跟踪某个服务的日志,我必须使用单独的 pod 来跟踪,因为 kubectl 不允许你根据标签选择器来跟踪。这并不理想,但对于大多数的使用情况来说是可行的。
只要 pod 没有崩溃或者没有被替换,这就可以了。如果 pod 或节点被终止了,日志就会永远丢失。另外,kubectl 只存储最近的日志,所以当我们想要前一天或更早的日志时,我们是盲目的。此外,不得不从 Grafana 跳到 CLI 再跳回来的做法并不理想。我们需要一个能减少上下文切换的解决方案,而我们探索的许多解决方案都非常昂贵,或者不能很好地扩展。
这是意料之中的事,因为它们比 select + grep 做得更多,而这正是我们所需要的。在看了现有的解决方案后,Grafana Labs 决定建立自己的。
由于对任何开源的解决方案都不满意,Grafana Labs 开始与人交谈,发现很多人都有同样的问题。事实上,Grafana Labs 已经意识到,即使在今天,很多开发人员仍然在 SSH 和 grep/tail 机器上的日志。他们所使用的解决方案要么太贵,要么不够稳定。事实上,人们被要求减少日志,Grafana Labs 认为这是一种反模式的日志。Grafana Labs 认为可以建立一些 Grafana Labs 内部和更广泛的开源社区可以使用的东西。Grafana Labs 有一个主要目标:

Grafana Labs 还瞄准了其他目标:
最后一点很重要。Grafana Labs 已经从 Prometheus 收集了指标的元数据,所以想利用这些元数据进行日志关联。例如,Prometheus 用 namespace、service name、实例 IP 等来标记每个指标。当收到警报时,使用元数据来找出寻找日志的位置。如果设法用同样的元数据来标记日志,我们就可以在度量和日志之间无缝切换。你可以在 这里 看到 Grafana Labs 写的内部设计文档。下面是 Loki 的演示视频链接:
根据 Grafana Labs 建立和运行 Cortex 的经验--作为服务运行的 Prometheus 的水平可扩展的分布式版本--想出了以下架构:

指标和日志之间的元数据匹配对我们来说至关重要,Grafana Labs 最初决定只针对 Kubernetes。想法是在每个节点上运行一个日志收集代理,用它来收集日志,与 kubernetes 的 API 对话,为日志找出正确的元数据,并将它们发送到一个中央服务,可以用它来显示在 Grafana 内收集的日志。
该代理支持与 Prometheus 相同的配置(relabelling rules),以确保元数据的匹配。我们称这个代理为 promtail。
深入 Loki —— 可扩展的日志收集引擎:

写入路径和读取路径(查询)是相互脱钩的,分开说明:

一旦 promtail 收集并发送日志到 Loki,Distributor 是第一个接收日志的组件。现在,Loki 可能每秒收到数百万条写,我们不想在它们进来时就把它们写到数据库中。那会搞宕任何数据库。需要在数据进入时对其进行批处理和压缩。
Grafana Labs 通过构建压缩的数据块 (chunks),通过 gzip 压缩日志来实现这一点。ingester(采集器) 组件是一个有状态组件,负责构建块,然后再刷新块。Loki 有多个 ingester,属于每个流的日志应该总是在同一个 ingester 中结束,因为所有相关条目都在同一个块中结束。通过构建一个 ingester 环 (ring) 并使用一致性哈希来做到这一点。当有条目进入时,分 Distributor 对日志的标签进行哈希处理,然后根据哈希值查找将条目发送到哪个 ingester。

此外,为了实现冗余和弹性,Loki 将其复制了 n 次(默认为 3 次)。
现在,Ingester 将接收条目并开始构建块。

这基本上是对日志进行 gzip 处理并追加。一旦块 "填满 "了,我们就把它刷到数据库中。我们为块(ObjectStorage)和索引使用不同的数据库,因为它们存储的数据类型是不同的。

刷完一个块后,Ingester 会创建一个新的空块,并将新条目添加到该块中。
读取路径非常简单,由 Querier 来完成大部分繁重的工作。给定一个时间范围和标签选择器,它查看索引以找出匹配的块,并通过它们进行搜索,给你结果。它还与 ingesters 对话,以获得尚未被刷到库中的最新数据。
请注意,在 2019 年版本中,对于每个查询,一个 Ingester 为你搜索所有相关的日志。Grafana Labs 已经在 Cortex 中使用前端实现了查询并行化,同样的方法可以扩展到 Loki,以提供分布式的 grep,这将使大型查询变得足够迅速。

说到 ingester,它是一个有状态的组件,但 Loki 已经将完整的分片和重新分片的生命周期纳入其中。当 rollout 工作完成后,或者当 ingester 被扩大或缩小时,环形拓扑结构会发生变化,ingester 会重新分配它们的块,以匹配新的拓扑结构。这主要是取自 Cortex 的代码,它已经在生产中运行了 5 年多。
Loki: like Prometheus, but for logs.
Loki 是一个水平可扩展、高可用、多租户的日志聚合系统,其灵感来自于 Prometheus。它被设计成非常具有成本效益和易于操作。它不对日志的内容进行索引,而是为每个日志流提供一组标签。
三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
这里是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基础版实例只有一个数据库节点,没有备节点作为热备份,因此当该节点意外宕机或者执行重启实例、变更配置、版本升级等任务时,会出现较长时间的不可用。如果业务对数据库的可用性要求较高,不建议使用基础版实例,可选择其他系列(如高可用版),部分基础版实例也支持升级为高可用版。基础版与高可用版的对比拓扑图如下所示。优势 性能由于不提供备节点,主节点不会因为实时的数据库复制而产生额外的性能开销,因此基础版的性能相对于
Region是HBase数据管理的基本单位,region有一点像关系型数据的分区。region中存储这用户的真实数据,而为了管理这些数据,HBase使用了RegionSever来管理region。Region的结构hbaseregion的大小设置默认情况下,每个Table起初只有一个Region,随着数据的不断写入,Region会自动进行拆分。刚拆分时,两个子Region都位于当前的RegionServer,但处于负载均衡的考虑,HMaster有可能会将某个Region转移给其他的RegionServer。RegionSplit时机:当1个region中的某个Store下所有StoreFile
我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts
如何在出现异常时指定全局救援,如果您将Sinatra用于API或应用程序,您将如何处理日志记录? 最佳答案 404可以在not_found方法的帮助下处理,例如:not_founddo'Sitedoesnotexist.'end500s可以通过调用带有block的错误方法来处理,例如:errordo"Applicationerror.Plstrylater."end错误的详细信息可以通过request.env中的sinatra.error访问,如下所示:errordo'Anerroroccured:'+request.env['si
我正在使用ruby标准记录器,我想要每天轮换一次,所以在我的代码中我有:Logger.new("#{$ROOT_PATH}/log/errors.log",'daily')它运行完美,但它创建了两个文件errors.log.20130217和errors.log.20130217.1。如何强制它每天只创建一个文件? 最佳答案 您的代码对于长时间运行的应用程序是正确的。发生的事情是您在给定的一天多次运行代码。第一次运行时,Ruby会创建一个日志文件“errors.log”。当日期改变时,Ruby将文件重命名为“errors.log
在运行Cucumber测试时,我得到(除了测试结果)大量调试/日志相关的输出形式:D,[2013-03-06T12:21:38.911829#49031]DEBUG--:SOAPrequest:D,[2013-03-06T12:21:38.911919#49031]DEBUG--:Pragma:no-cache,SOAPAction:"",Content-Type:text/xml;charset=UTF-8,Content-Length:1592W,[2013-03-06T12:21:38.912360#49031]WARN--:HTTPIexecutesHTTPPOSTusingt