ARMS提供了常见的应用监控指标,如果您需要自定义指标,可以引入OpenTelemetry Java SDK实现。本文介绍如何自定义指标并在Grafana中查询自定义指标。
前提条件
已经成功接入ARMS应用监控,具体操作,请参见应用接入。
ARMS探针版本为 4.5.0 及以上版本。
引入依赖
请先参考如下Maven代码引入OpenTelemetry Java SDK。更多信息,请参见OpenTelemetry官方文档。
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.23.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
自定义指标步骤
OpenTelemetry 当前支持的指标类型大体有以下四类,目前除了Histogram(直方图),其余类型ARMS都支持。
Counter(计数器) 用途:记录单调递增的累积值(只能增加,不能减少)。 示例:HTTP 请求总数、错误发生次数。
UpDownCounter(可增减计数器) 用途:记录可增减的非单调值(如当前活跃连接数)。 示例:并发请求数、队列中的任务数。
Histogram(直方图,暂不支持) 用途:记录值的分布(如延迟、响应大小),支持计算分位数。 示例:请求延迟分布(P90、P95)、文件上传大小。
Gauge(仪表) 用途:捕获某一时刻的瞬时值(如 CPU 使用率、内存占用)。 示例:系统温度、实时内存使用量。
步骤1:代码中增加自定义指标
下面的代码是一段抢购商品的简单示例代码,其中定义了两个指标:
product_seckill_count:抢购次数
product_current_stock:当前库存
其中在获取定义指标的工厂类 meter 时,传入了一个product_seckill
参数,这个可以理解为一个分组的概念,后续通过该 meter 定义的指标都在该分组下,后续配置中会用到该分组。
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.metrics.ObservableLongGauge;
import javax.annotation.PreDestroy;
import java.util.concurrent.atomic.AtomicInteger;
class ProductService {
// 静态库存计数器
public final AtomicInteger stock = new AtomicInteger(0);
private LongCounter seckillCounter;
private ObservableLongGauge observableLongGauge;
private final AttributeKey<String> seckillResult = AttributeKey.stringKey("seckill_result");
public ProductService() {
OpenTelemetry agentOpenTelemetry = GlobalOpenTelemetry.get();
//定义指标工厂类,注意这里的product_seckill很重要
Meter meter = agentOpenTelemetry.getMeter("product_seckill");
//定义一个counter指标,用于记录商品抢购的次数
seckillCounter = meter.counterBuilder("product_seckill_count")
.setUnit("1")
.setDescription("seckill product count")
.build();
//定义一个gauge指标,代表当前库存的商品数量
observableLongGauge = meter.gaugeBuilder("product_current_stock").ofLongs().buildWithCallback((measurement -> {
//记录当前商品数量
measurement.record(stock.get());
}));
}
@PreDestroy
public void clear() {
observableLongGauge.close();
}
public void setKillProductCount(int count) {
stock.set(count);
}
public String seckillProduct() {
int currentStock = stock.get();
if (currentStock <= 0) {
seckillCounter.add(1, Attributes.of(seckillResult, "failed"));
return "抢购失败,商品已售罄";
}
// 尝试扣减库存
if (stock.decrementAndGet() >= 0) {
seckillCounter.add(1, Attributes.of(seckillResult, "success"));
return "抢购成功,剩余库存:" + stock.get();
} else {
stock.incrementAndGet(); // 回滚
seckillCounter.add(1, Attributes.of(seckillResult, "success"));
return "抢购失败,商品已售罄";
}
}
}
步骤2:在控制台配置指标采集
在控制台修改自定义指标采集配置,新增上一步创建 meter 时填入的参数。
步骤3:查看指标并配置告警
在ARMS控制台的 页面顶部菜单栏选择应用接入的地域。
实例类型为Prometheus for 应用监控的实例即为默认集成的应用监控实例。
单击右侧共享版进入 Grafana 页面,然后单击 Explore,选择数据源为上一步对应的 Prometheus 实例名称。
您可以通过 PromQL 简单查询在代码中定义的指标,如下图所示,也可以在 Grafana 中自定义展示大盘。
自此通过 OpenTelemetry SDK 定义的指标就已经成功上报并存储到 ARMS 服务端 Prometheus 存储实例中了,后续您可以对 Prometheus 存储实例中的指标创建告警规则。
注意事项
目前 ARMS 指标上报间隔为 15 秒一次。
对于 Counter 类指标,ARMS 目前上报的不是累计值,而是一个上报周期内的增加值,即每 15 秒该指标的增加值。