SonarQube自定义指标添加报错求助:Metric should not be computed by a Sensor
解决SonarQube自定义指标报错:Metric should not be computed by a Sensor
这个报错我之前帮不少插件开发者排查过,本质是SonarQube对自定义指标的计算逻辑有明确分工:你在管理界面创建的自定义指标属于衍生计算指标,这类指标不允许直接用Sensor写入;而像Fan In这种需要从代码解析中直接获取的原始指标,得用插件代码定义后再通过Sensor收集。下面给你两种适配场景的解决方案:
解决方案1:用插件代码定义原始指标(推荐)
Fan In属于需要直接解析代码依赖关系的原始指标,最适合用这种方式:
步骤1:在插件中注册自定义Metric
不要在UI创建指标了,直接在你的插件主类里定义并注册这个指标:
public class YourLegacyLanguagePlugin extends SonarPlugin { @Override public List<Object> getExtensions() { return List.of( // 定义Fan In指标 Metric.builder("fan_in") .setName("Fan In") .setDescription("Number of components that depend on this file") .setType(Metric.ValueType.INT) .setDirection(Metric.DIRECTION_WORST) // 可选:如果值越大越需要关注,设置这个 .setQualitative(false) .build(), // 注册你的传感器 YourLegacyLanguageSensor.class ); } }
步骤2:在Sensor中计算并写入指标
修改你的传感器代码,直接使用上面定义的指标键来写入计算值:
public class YourLegacyLanguageSensor implements Sensor { // 引用定义好的Fan In指标 private final Metric<Integer> fanInMetric = Metric.key("fan_in").as(Integer.class); @Override public void execute(SensorContext context) { // 遍历当前语言的所有输入文件 InputFilePredicate predicate = context.fileSystem().predicates().hasLanguage("your-legacy-language-key"); for (InputFile file : context.fileSystem().inputFiles(predicate)) { // 调用你的解析逻辑计算Fan In值 int fanInValue = calculateFanInFromCode(file); // 将结果写入SensorContext context.<Integer>newMeasure() .on(file) .forMetric(fanInMetric) .withValue(fanInValue) .save(); } } // 这里替换成你实际的代码解析逻辑 private int calculateFanInFromCode(InputFile file) { // 示例:解析文件依赖关系,返回Fan In数值 return 5; } @Override public void describe(SensorDescriptor descriptor) { descriptor.name("Your Legacy Language Fan In Sensor") .onlyOnLanguage("your-legacy-language-key"); } }
解决方案2:用MeasureComputer适配UI创建的衍生指标
如果你一定要保留UI创建的自定义指标(比如不想修改插件代码结构),那得用MeasureComputer来间接计算,而不是Sensor:
步骤1:实现MeasureComputer类
这个类负责基于已有原始指标计算出UI自定义指标的值:
public class FanInMeasureComputer implements MeasureComputer { @Override public MeasureComputerDefinition define(MeasureComputerDefinitionContext context) { return context.newDefinitionBuilder() // 输入指标:填你用来计算Fan In的原始指标键(比如你已经收集的依赖指标) .setInputMetrics("dependency_count") // 输出指标:填你在UI创建的自定义指标键 .setOutputMetrics("custom_fan_in") .build(); } @Override public void compute(MeasureComputerContext context) { // 获取输入指标的数值 Integer dependencyCount = context.getMeasureValue("dependency_count"); if (dependencyCount != null) { // 替换成你的Fan In计算逻辑 int fanInValue = dependencyCount; // 将结果写入UI创建的指标 context.addMeasure("custom_fan_in", fanInValue); } } }
步骤2:在插件中注册MeasureComputer
把这个计算类加到插件的扩展列表里:
public class YourLegacyLanguagePlugin extends SonarPlugin { @Override public List<Object> getExtensions() { return List.of( FanInMeasureComputer.class, // 其他扩展(比如你的Sensor) ); } }
关键提醒
- UI创建的自定义指标本质是衍生指标,只能基于已有指标通过MeasureComputer计算,不能由Sensor直接写入,这就是你报错的核心原因。
- Fan In这类需要解析代码结构的指标,属于原始指标,优先用方案1实现,逻辑更清晰也符合SonarQube的设计规范。
内容的提问来源于stack exchange,提问作者Markus A.
相关产品推荐
相关产品推荐

