New Relic Java 的 recordMetric 为什么看不到自定义指标?
这段 recordMetric 调用的参数没有明显错误。原查询没有指定 APM 应用,应先补上应用条件。New Relic 官方要求查询 APM metric timeslice 数据时指定数据源,例如 entity.guid、appId 或 appName。目前可以确认原查询缺少这一条件,但指标不可见还可能有其他原因。官方查询说明
recordMetric 记录的是什么数据?
Java API 的签名是:
public static void recordMetric(String name, float value)
示例中的整数可以由 Java 自动转换为 float,不需要强制类型转换。Custom/TestData/RequestsPerSecond 也符合 Custom/ 前缀要求。Java API 文档、自定义指标命名说明
这类自定义指标按 metric timeslice 聚合。查询时,将指标名称放在 metricTimesliceName 条件中,通过 newrelic.timeslice.value 聚合读取数值。能查到 recordCustomEvent 记录的事件,说明该事件已成功上报;这不能证明指标也已成功上报并被正确查询。
先指定应用,再查指标
在正确的 New Relic 账号中打开 Query builder,将下面的 YOUR_APP_NAME 替换为该 JVM 实际上报的 APM 应用名称:
SELECT uniques(metricTimesliceName)
FROM Metric
WHERE appName = 'YOUR_APP_NAME'
AND newrelic.timeslice.value IS NOT NULL
AND metricTimesliceName LIKE 'Custom/TestData%'
SINCE 1 hour ago
先列出指标名称,检查该应用下是否有匹配的指标。首次检查时,这种方式比 SELECT * 更合适。然后查询具体数值:
SELECT average(newrelic.timeslice.value) AS 'Average value',
count(newrelic.timeslice.value) AS 'Samples'
FROM Metric
WHERE appName = 'YOUR_APP_NAME'
AND metricTimesliceName = 'Custom/TestData/RequestsPerSecond'
SINCE 1 hour ago
TIMESERIES
也可以用 entity.guid = 'YOUR_ENTITY_GUID' 替换应用条件,明确限定目标实体。这些查询基于官方的自定义 timeslice 指标查询方法。查询示例与聚合函数说明
用固定值确认调用和上报
排查时先去掉随机数,保留相同的指标名:
import com.newrelic.api.agent.NewRelic;
public String simpleFunction() {
NewRelic.recordMetric("Custom/TestData/RequestsPerSecond", 42.0f);
return "Hi";
}
确认部署后的代码确实执行到这一行,并持续触发调用。根据官方对自定义指标测试的建议,让应用和 agent 保持运行至少 10 分钟后再查询。刚调用完就查不到指标,不能说明调用失败。自定义指标测试建议
如果结果仍然为空,可以按以下顺序排查:
- 核对执行该方法的进程、环境和 APM 应用,确认查询的不是其他实例所属的应用。
- 用临时日志或断点确认实际执行路径,记录调用时间,并让查询窗口覆盖该时间。
- 查看该 JVM 对应的 agent 日志,检查连接、指标上报错误或数据丢弃提示。即使其他 API 正常,也应检查日志。
- 查询同一应用已有的 APM 指标。如果已有指标也查不到,优先检查账号、应用筛选和时间范围;如果已有指标正常而目标指标缺失,再检查自定义调用路径及相关日志。
原问题没有提供 agent 版本、调用频率和日志,目前无法确定问题出在运行路径、上报还是查询环节,也没有依据直接归因于某个版本缺陷。
指标名称不会自动计算每秒请求数
原代码每调用一次就记录一个随机数。指标名称虽然叫 RequestsPerSecond,记录的值并不会自动变成真实 TPS。
如果你已经在业务代码中算出了每秒请求数,可以继续用 recordMetric 记录该测量值。如果希望统计这个方法每秒执行多少次,可以在每次执行时记录一个样本:
NewRelic.recordMetric("Custom/TestData/RequestCount", 1.0f);
再按样本数量计算每秒速率:
SELECT rate(count(newrelic.timeslice.value), 1 second)
AS 'Requests per second'
FROM Metric
WHERE appName = 'YOUR_APP_NAME'
AND metricTimesliceName = 'Custom/TestData/RequestCount'
SINCE 30 minutes ago
TIMESERIES
这个计算的前提是每个目标请求恰好记录一次。count(newrelic.timeslice.value) 统计记录次数,不会把传入的随机数当成请求数量。结果是查询时间桶内的每秒速率,不代表逐秒原始明细。官方聚合与吞吐量查询示例
备注:内容仅供参考。
