指标编辑

Java 代理跟踪某些系统和应用程序指标。其中一些指标具有内置的可视化功能,而另一些则只能通过自定义 Kibana 仪表板进行可视化。

这些指标将定期发送到 APM 服务器,然后从那里发送到 Elasticsearch。您可以使用设置 metrics_interval 调整间隔。

指标将存储在 apm-* 索引中,并具有设置为 metricprocessor.event 属性。

从 Elastic Stack 版本 7.2 开始,提供专门的 JVM 指标视图。从 7.5 开始,每个 JVM 的指标将单独聚合,依赖于底层系统的 ID - 容器 ID(如果适用)或主机名。从 Java 代理版本 1.11.0 开始,可以通过 service_node_name 手动配置每个服务节点/JVM 的唯一名称。当多个 JVM 在同一主机上运行并为同一服务报告数据时,需要此配置才能在 JVM 级别查看指标。

系统指标编辑

主机指标。从版本 6.6 开始,这些指标将在 APM 应用程序中可视化。

有关更多系统指标,请考虑在您的主机上安装 metricbeat

system.cpu.total.norm.pct

类型:scaled_float

格式:百分比

除空闲和 IOWait 之外的状态下的 CPU 时间百分比,按核心数量进行归一化。

system.process.cpu.total.norm.pct

类型:scaled_float

格式:百分比

自上次事件以来,进程花费的 CPU 时间百分比。此值按 CPU 核心数量进行归一化,范围为 0 到 100%。

system.memory.total

类型:long

格式:字节

总内存。

system.memory.actual.free

类型:long

格式:字节

实际可用内存(以字节为单位)。它是根据操作系统计算的。在 Linux 上,它包括可用内存加上缓存和缓冲区。在 OSX 上,它是可用内存和非活动内存的总和。在 Windows 上,此值不包括系统缓存和缓冲区使用的内存。

system.process.memory.size

类型:long

格式:字节

进程拥有的总虚拟内存。

cgroup 指标(在 1.18.0 中添加)编辑

Linux 的 cgroup 指标。

system.process.cgroup.memory.mem.limit.bytes

类型:long

格式:字节

当前 cgroup 片段的内存限制。

system.process.cgroup.memory.mem.usage.bytes

类型:long

格式:字节

当前 cgroup 片段的内存使用量。

JVM 指标编辑

JVM 特定指标

jvm.memory.heap.used

类型:long

格式:字节

已使用的堆内存量(以字节为单位)

jvm.memory.heap.committed

类型:long

格式:字节

为 Java 虚拟机使用而提交的堆内存量(以字节为单位)。此内存量保证可供 Java 虚拟机使用。

jvm.memory.heap.max

类型:long

格式:字节

可用于内存管理的堆内存最大量(以字节为单位)。如果最大内存大小未定义,则值为 -1

jvm.memory.heap.pool.used

类型:long

格式:字节

name 标签指定的堆内存池中已使用的内存量(以字节为单位)

标签

  • name:表示此内存池的名称
jvm.memory.heap.pool.committed

类型:long

格式:字节

为由 name 标签指定的堆内存池使用而提交的内存量(以字节为单位)。此内存量保证可供此特定池使用。

标签

  • name:表示此内存池的名称
jvm.memory.heap.pool.max

类型:long

格式:字节

可用于由 name 标签指定的堆内存池的内存最大量(以字节为单位)。

标签

  • name:表示此内存池的名称
jvm.memory.non_heap.used

类型:long

格式:字节

已使用的非堆内存量(以字节为单位)

jvm.memory.non_heap.committed

类型:long

格式:字节

为 Java 虚拟机使用而提交的非堆内存量(以字节为单位)。此内存量保证可供 Java 虚拟机使用。

jvm.memory.non_heap.max

类型:long

格式:字节

可用于内存管理的非堆内存最大量(以字节为单位)。如果最大内存大小未定义,则值为 -1

jvm.memory.non_heap.pool.used

类型:long

格式:字节

name 标签指定的非堆内存池中已使用的内存量(以字节为单位)

标签

  • name:表示此内存池的名称
jvm.memory.non_heap.pool.committed

类型:long

格式:字节

为由 name 标签指定的非堆内存池使用而提交的内存量(以字节为单位)。此内存量保证可供此特定池使用。

标签

  • name:表示此内存池的名称
jvm.memory.non_heap.pool.max

类型:long

格式:字节

可用于由 name 标签指定的非堆内存池的内存最大量(以字节为单位)。

标签

  • name:表示此内存池的名称
jvm.thread.count

类型:int

JVM 中当前活动线程数,包括守护线程和非守护线程。

jvm.gc.count

类型:long

标签

  • name:表示此内存管理器的名称(例如 G1 Young GenerationG1 Old Generation

已发生的收集总数。

jvm.gc.time

类型:long

格式:毫秒

标签

  • name:表示此内存管理器的名称(例如 G1 Young GenerationG1 Old Generation

近似累积的收集经过时间(以毫秒为单位)。

jvm.gc.alloc

类型:long

格式:字节

堆内存中分配的总内存量(以字节为单位)的近似值。

jvm.fd.used

类型:long

当前打开的文件描述符数量。

jvm.fd.max

类型:long

打开的文件描述符的最大数量。

JMX 指标编辑

Java 管理扩展 (JMX) 为 JVM 提供了一个通用的管理接口,通常用于通过此接口公开内部指标。

Elastic APM 代理能够直接连接到 JMX 接口,而无需其他凭据或更改 JVM 参数,这与其他外部工具(如 VisualVM 或 Jconsole)不同。此外,它只捕获指标,不会将整个 JMX 管理接口公开给最终用户。

要捕获的 JMX 指标需要通过 capture_jmx_metrics 选项进行配置。

内置应用程序指标编辑

为了支持 按跨度类型划分的时间 图表,代理会收集有关跨度和事务的计时信息的汇总指标,按跨度类型细分。

span.self_time

类型:简单计时器

此计时器跟踪跨度自计时,是事务细分可视化的基础。

字段

  • sum.us:自上次报告(增量)以来所有跨度自计时之和(以微秒为单位)
  • count:自上次报告(增量)以来所有跨度自计时次数

您可以按以下维度进行筛选和分组

  • transaction.name:事务的名称
  • transaction.type:事务的类型,例如 request
  • span.type:跨度的类型,例如 apptemplatedb
  • span.subtype:跨度的子类型,例如 mysql(可选)

仅使用代理进行指标收集编辑

在某些情况下,您可能希望仅使用代理来收集和发送指标,而不会跟踪任何 Java 代码。在这种情况下,您可以将 instrument 配置选项设置为 false。通过这样做,代理将最大限度地减少其对应用程序的影响,同时仍然收集指标并将其发送到 APM 服务器。

OpenTelemetry 指标编辑

Elastic APM Java 代理支持收集通过 OpenTelemetry 定义的指标。有关详细信息,请参阅相应的 文档部分

Micrometer 指标编辑

此功能处于测试阶段,可能会发生变化。设计和代码不如正式 GA 功能成熟,按原样提供,不提供任何担保。测试版功能不受正式 GA 功能支持 SLA 的约束。

Elastic APM Java 代理允许您使用流行的指标收集框架 Micrometer 来跟踪自定义应用程序指标。

跟踪应用程序自定义指标的一些用例包括监控与性能相关的指标,例如缓存统计信息、线程池或页面点击率。但是,您还可以跟踪与业务相关的指标(如收入)并将它们与性能指标相关联。注册到 Micrometer MeterRegistry 的指标在内存中聚合,并每隔 metrics_interval 报告一次。根据有关服务和时间戳的元数据,您可以将指标与跟踪相关联。优势在于,指标不会受到 采样率 的影响,并且通常占用更少的空间。这是因为并非每个事件都单独存储。

跟踪指标的局限性在于,您无法将值归因于特定事务。如果您想这样做,请 向事务添加标签,而不是使用 Micrometer 跟踪指标。这里的权衡是,您要么必须进行 100% 采样,要么必须考虑丢失的事件。原因是,如果您将采样率设置为 10%,例如,您将只存储 10 个请求中的一个。您在未采样事务上设置的标签将丢失。

说明编辑

  • Micrometer 指标的度量名称中的点将被替换为下划线,以避免映射冲突。可以通过 dedot_custom_metrics 禁用去点操作。
  • 直方图(DistributionSummaryTimerLongTaskTimer)通过将直方图指标转换为三个派生指标来支持:值的计数器、值的总和以及 直方图。例如,DistributionSummary.builder("order").register(...).record(orderPrice) 将创建三个指标:order.sumorder.countorder.histogram(它具有用于桶的 values 数组和用于每个桶中样本计数的 counts 数组)。
  • 当使用多个 MeterRegistry 时,指标将根据其指标 ID 去重。如果在复合指标注册表中从多个指标注册表发生冲突,则会发出警告。
  • 当使用 CountingMode.CUMULATIVE 时,可以使用 TSVB 的“正比率”聚合将计数器转换为比率。但您必须记住按唯一标识时间序列的维度组合进行分组。这可能是 host.nameservice.name 的组合,或者 kubernetes.pod.id

使用现有的 Micrometer 设置开始编辑

附加代理,您就完成了!代理会自动检测所有 MeterRegistry 实例并将所有指标报告给 APM Server(除了它们最初报告的位置)。在应用程序启动后附加代理时,代理会在调用 MeterRegistry 上的任何公共方法时检测到它。如果您在 CompoundMeterRegistry 中使用多个注册表,代理只会报告一次指标。

验证 Micrometer 数据编辑

使用 Discover 验证指标是否已成功报告到 Kibana。

  1. 启动 Kibana。
  2. 打开主菜单,然后单击 Discover
  3. 选择 apm-* 作为您的索引模式。
  4. 过滤数据以仅显示包含指标的文档:processor.name :"metric"
  5. 如果 Micrometer 仅在您环境的子集中进行检测,则可以选择按服务或主机名称应用其他过滤器。

您现在应该看到包含 APM 代理收集的指标和 Micrometer 的自定义指标的文档。使用已知的 Micrometer 指标字段缩小您的搜索范围。例如,如果您知道已在 Micrometer MeterRegistry 中注册了指标名称 cache.puts,请将 cache_puts: *(点将被替换为下划线)添加到您的搜索中,以仅返回 Micrometer 指标文档。

可视化 Micrometer 数据编辑

单调递增计数器和正比率聚合在当前版本中不受完全支持。

TSVB 是 Micrometer 指标的推荐可视化方法。首先,确保选择正确的聚合。最常见的选项是

  • 总和:适用于业务指标
  • 平均值:通常用于与性能相关的指标

通常按属性对指标进行分组,包括 Micrometer 标签或 APM 代理已收集的属性。这可能是服务版本、运行时版本,甚至云元数据。

有关更多信息,请参阅 TSVB 中的事件速率和变化速率 博客文章。

从头开始编辑

声明对 Micrometer 的依赖项

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>${micrometer.version}</version>
</dependency>

创建一个 Micrometer MeterRegistry

MeterRegistry registry = new SimpleMeterRegistry(new SimpleConfig() {

        @Override
        public CountingMode mode() {
            // to report the delta since the last report
            // this makes building dashbaords a bit easier
            return CountingMode.STEP;
        }

        @Override
        public Duration step() {
            // the duration should match metrics_interval, which defaults to 30s
            return Duration.ofSeconds(30);
        }

        @Override
        public String get(String key) {
            return null;
        }
    }, Clock.SYSTEM);

开始使用 Spring Boot编辑

使用 Spring Boot 的最简单方法是添加对 Spring Boot Actuator 的依赖项。Spring Boot Actuator 为 Micrometer 提供依赖项管理和自动配置。

使用 management.metrics.export.simple 前缀通过 application.properties 进行配置

management.metrics.export.simple.enabled=true
management.metrics.export.simple.step=30s
management.metrics.export.simple.mode=STEP

支持的指标编辑

本节列出了所有支持的 Micrometer Meter 并描述了它们如何映射到 Elasticsearch 文档。

Micrometer 标签嵌套在 labels 下。示例

"labels": {
  "tagKey1": "tagLabel1",
  "tagKey2": "tagLabel2",
}

标签非常适合按不同维度细分指标。虽然没有上限,但请注意,每个标签的独特值数量(即高基数)可能会导致更高的内存使用量、更高的索引大小和更慢的查询。此外,请确保独特标签键的数量有限,以避免 映射爆炸

根据指标类型,某些指标可能会作为多个指标导出到 Elasticsearch。下面显示了每种指标类型的结果字段。请注意,disable_metrics 选项对指标的原始名称起作用,而不是对生成的字段起作用。因此,只能禁用给定指标的所有字段,而不能禁用单个字段。

计时器

字段

  • ${name}.sum.us:记录事件的总时间(使用 CountingMode.STEP 时为增量)。这等效于 timer.totalTime(TimeUnit.MICROSECONDS)
  • ${name}.count:在此计时器上调用停止的次数(使用 CountingMode.STEP 时为增量)。这等效于 timer.count()
函数计时器

字段

  • ${name}.sum.us:计时事件的所有发生事件的总时间(使用 CountingMode.STEP 时为增量)。这等效于 functionTimer.totalTime(TimeUnit.MICROSECONDS)
  • ${name}.count:计时事件的总发生次数(使用 CountingMode.STEP 时为增量)。这等效于 functionTimer.count()
长时间任务计时器

字段

  • ${name}.sum.us:所有当前任务的累积持续时间(使用 CountingMode.STEP 时为增量)。这等效于 longTaskTimer.totalTime(TimeUnit.MICROSECONDS)
  • ${name}.count:正在执行的任务的当前数量(使用 CountingMode.STEP 时为增量)这等效于 longTaskTimer.activeTasks()
分布摘要

字段

  • ${name}.sum:所有记录事件的总量(使用 CountingMode.STEP 时为增量)。这等效于 distributionSummary.totalAmount()
  • ${name}.count:调用记录的次数(使用 CountingMode.STEP 时为增量)。这等效于 distributionSummary.count()
仪表

字段

  • ${name}gauge.value() 的值。
计数器

字段

  • ${name}counter.count() 的值(使用 CountingMode.STEP 时为增量)。
函数计数器

字段

  • ${name}functionCounter.count() 的值(使用 CountingMode.STEP 时为增量)。

代理运行状况指标编辑

此功能处于技术预览阶段,可能会在将来的版本中更改或删除。Elastic 将努力解决任何问题,但技术预览中的功能不受官方 GA 功能支持 SLA 的约束。

代理在内部使用队列来缓冲各种事件(例如事务、跨度、指标),然后再将它们发送到 APM 服务器。当 agent_reporter_health_metrics 启用时,代理将公开有关此队列的运行状况以及与 APM 服务器的网络连接的几个指标。此外,如果 agent_background_overhead_metrics 启用,代理将持续测量其自身后台任务的资源消耗,并将结果作为指标提供。

代理报告和事件指标编辑

agent.events.total

类型:long

格式:事件数

尝试向 APM 服务器报告的事件总数。

agent.events.dropped

类型:long

格式:事件数

无法发送到 APM 服务器的事件数,例如由于队列已满或出现错误。

agent.events.queue.min_size.pct

类型:双精度

格式:百分比 [0-1]

自上次指标报告以来的报告队列的最小大小。

agent.events.queue.max_size.pct

类型:双精度

格式:百分比 [0-1]

自上次指标报告以来的报告队列的最大大小。

agent.events.requests.count

类型:long

格式:请求数

向 APM 服务器发出的请求数(成功和失败)。

agent.events.requests.bytes

类型:long

格式:字节

尝试发送到 APM 服务器以报告数据的字节数(成功和失败)。

代理后台资源消耗指标编辑

agent.background.cpu.total.pct

类型:双精度

格式:百分比 [0-1]

代理中运行的后台任务导致的总 CPU 使用率。

agent.background.cpu.overhead.pct

类型:双精度

格式:百分比 [0-1]

代理中运行的后台任务导致的进程 CPU 使用率的份额。

agent.background.memory.allocation.bytes

类型:long

格式:字节

代理中运行的后台任务在堆中分配的字节数。

agent.background.threads.count

类型:long

格式:线程数

代理中后台任务使用的线程数。