[spring-projects/spring-boot]发布应用程序启动时间的指标

2024-06-26 901 views
6

我想随着时间的推移监控我们的 Spring Boot 应用程序的完整启动时间。我可以看到ApplicationStartupSpring 中的界面包含有关不同步骤启动时间的详细信息,但我认为最好将总体启动时间作为指标。

我真的很喜欢它StartupInfoLogger包含 JVM/应用程序的启动时间,并将其作为指标,让我们能够通过千分尺将其发送到外部度量系统并随时间进行监控。

看完ApplicationStartup信息后,我不确定是否有一个好的汇总来显示以下内容StartupInfoLogger

[06-01-21 16:00:13.878] [main] INFO   c.p.r.web.LocalApplicationRunner - Started LocalApplicationRunner in 16.605 seconds (JVM running for 17.318)

回答

8

@mbazos 您见过ApplicationStartup吗?我可以看到使用此端点的输出来发出指标,或者创建一个ApplicationStartup发出指标的自定义实现。

0

@bono007 我最初查看了 ApplicationStartup,但查看了数据的捕获方式,我认为您需要获取第一个事件startTime和最后一个事件endTime,这样才能获得完整的应用程序启动时间吗?另外,我不确定这是否能像StartupInfoLogger

因此,我认为也许一个可以发出指标的自定义 ApplicationStartup 是一个好主意,但我更多地是在运行容器的应用程序的背景下考虑的,其中启动时间可能是关键指标。

我猜这是只知道总体总时间和知道所有个别细节之间的区别。我猜根据用例,人们可能想要两者,但我认为总体总时间可能更有价值,因为它可以作为一个很好的起点,然后人们会深入挖掘为什么他们的应用程序需要这么长时间。

3

bonoo007:您见过 ApplicationStartup 吗?

@mbazos 我的错,我看到您在原始消息中指定了这一点。

也许我们只是缺少timeline.endTime?

是的,我也注意到了。我不确定为什么不存在。也许 Spring Boot 团队可以对此提供一些见解。如果没有技术原因,我认为添加它会是一件好事。

那么您可以获得完全启动所需的时间并据此生成一个指标吗?

是的,我最初回答时就是这么想的。

此外,我认为这将涵盖 Spring 应用程序,但不包括 JVM 运行以来的时间

还存在UptimeMetrics,它利用JMX RuntimeMXBean进行启动和正常运行时间(JMV 视角),这可能对您的情况有帮助。

深入挖掘为什么他们的申请需要这么长时间。

我希望 JavaFlightRecorderApplicationStartup 是进行深入挖掘的良好候选者。

7

是的,我认为无论何时您想深入挖掘,JFR 都将成为事实上的工具。

总结一下这个问题,也许问题是:

  • 为什么没有 timeline.endTime?如果没有技术原因,是否可以添加它?
  • 如果ApplicationStartup可以记录微米度量,或者应该UptimeMetrics这样做,那会很好吗?

如果我有某个方向,我不会介意从事 PR 工作,只要告诉我就行。

9

嗨@mbazos

我进行了一些调查并想分享一下结果:

时间线.结束时间

ApplicationStartup (AS) 契约非常精简,仅公开start返回的 API StartupStep。没有总体开始时间的概念 - 新步骤刚刚开始。也没有总体结束时间的概念,也没有时间线的概念。我很确定所有这些都是设计使然。将时间线的概念(包括开始和结束时间)添加到 ApplicationStartup 契约中将会引起不小的波澜。另一点是 AS 存在于 Spring Framework 中,而不是 Spring Boot 中。

StartupTimeline 特定于 BufferingApplicationStartup (BAS) 实现。向此实现添加结束时间非常简单。BAS 的时间线通过调用来启动startRecording。我们可以添加一个stopRecording标记总体结束时间的 API。然后可以将此 endTime 添加为 StartupTimeline 上的可空字段。该字段需要可空,因为 BAS 是一个有界的事件缓冲区,可以在启动序列期间随机耗尽和检索。因此,当在调用之前检索时间线时stopRecording,该endTime字段将为空。这种方法的一个缺点是结束时间仅在 BAS 实现中可用。

如果最终目标只是记录应用程序启动时间和结束时间的指标,那么引入 StartupTimeMetrics 可能更简单。根据上述发现,AppllcationStartup 可能不是最佳位置。

我很想知道 Spring Boot 团队的建议。

6

@mbazos 我认为已经有一些可用的东西可以用来推断启动时间。看看SpringApplicationRunListeners。每个生命周期步骤都记录了其开始/结束时间。我相信您可以获取"spring.boot.application.running"步骤的结束时间和 BufferingApplicationStartup startTime 来查看总启动时间。

2

@mbazos 您有机会看一下上述建议吗?

3

嘿,抱歉@bono007 回复迟了。我需要深入研究一下。是的,我认为您建议的方法可行,但我仍然想知道这是否应该由 spring-boot 核心处理,因为它已经打印了总时间/jvm 时间,将日志语句与可能生成的指标进行匹配似乎更简单、更直接。我喜欢您介绍的想法,StartupTimeMetrics我想问题是您用它SpringApplicationRunListeners来生成 StartupTimeMetrics 还是它是更简单的东西并StartupInfoLogger用于生成 StartupTimeMetrics?

此外,如果我们要创建,StartupTimeMetrics我们想要什么指标?

  • jvm启动时间
  • 申请开始时间
  • Spring 上下文启动时间
5

我们或许能够将启动时间包含在内ApplicationStartedEvent。然后某些东西可以监听该事件并发布指标。

7

我还没有对此进行过多研究,但看看#27475 中启动时间线周围添加的可观察性是否有助于解决这个问题可能会很有趣。

6

感谢@bono007的建议。目前,我看不出将这两个功能结合起来有什么好处。这是我们上周讨论这个问题时团队的想法的草图:https://github.com/wilkinsona/spring-boot/tree/gh-26729。在执行器端,将有一个监听器接收启动事件并发布指标。

0

我应该澄清一下(我发送链接时正在打电话,所以说得比较简短)。我本想把问题直接发给@mbazos,问他链接中的可观察性功能是否有助于(或足以)满足他的兴趣。我也不认为将它与通用解决方案结合起来是个好主意。

感谢您提供草图链接。我本来想添加它,但看起来您在解决方案的“在 ApplicationStartedEvent 中包含启动时间”部分已经完成了。您要继续使用执行器指标监听器端吗?如果您不打算继续,我很乐意使用它。

谢谢

4

@bono007 我很难找到一些额外的时间来处理这个问题,所以请继续做下去。

4

@mbazos 我不知怎么就错过了你的回复。我会尽快提交一份提案。

7

结束支持 PR #27878