Custom Metrics are lagging behind

I’ve developed a custom plugin with four rules, which works completely fine.
I’ve now extended it by custom metrics, so I can see the number of issues for rules that are defined in that plugin. The metrics are recognized by SonarQube, but the metric (number of issues) lags behind - I basically need to analyze a project twice for the correct metric.

The Metric:

package org.hbrs;

import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.measures.Metrics;

import java.util.List;

import static java.util.Arrays.asList;

public class EnergySmellCountMetric implements Metrics {

    public static final String KEY = "energy_smells";

    public static final Metric<Integer> ISSUES_COUNT = new Metric.Builder(KEY, "Energy Smells", Metric.ValueType.FLOAT)
            .setDescription("Counts the raised issues for the rules defined in the energy smell plugin.")
            .setDirection(Metric.DIRECTION_WORST)
            .setQualitative(false)
            .setDomain(CoreMetrics.DOMAIN_ISSUES)
            .setBestValue(0.0)
            .setDecimalScale(0)
            .create();

    @Override
    public List<Metric> getMetrics() {
        return asList(ISSUES_COUNT);
    }
}

The MeasureComputer:

package org.hbrs;

import org.sonar.api.ce.measure.Component;
import org.sonar.api.ce.measure.Measure;
import org.sonar.api.ce.measure.MeasureComputer;

import java.util.concurrent.atomic.AtomicLong;

import static org.hbrs.EnergySmellCountMetric.ISSUES_COUNT;

public class EnergySmellMeasureComputer implements MeasureComputer {
    private static final AtomicLong totalIssuesCount = new AtomicLong(0);

    @Override
    public MeasureComputerDefinition define(MeasureComputerDefinitionContext context) {
        return context.newDefinitionBuilder()
                .setInputMetrics()
                .setOutputMetrics(EnergySmellCountMetric.KEY)
                .build();
    }

    @Override
    public void compute(MeasureComputerContext context) {
        if (context.getIssues() == null) {
            context.addMeasure(ISSUES_COUNT.key(), 0);
            return;
        }
        System.out.println(context.getComponent().getKey() + ":    " + context.getIssues().size());
        context.getIssues().forEach(issue -> System.out.println(issue.ruleKey()));


        // Check if it is an energy smell (meaning it belongs to this plugin with the key "hbrs")
        long count = context.getIssues().stream()
                .filter(issue -> issue.ruleKey().repository().equals("hbrs"))
                .count();

        totalIssuesCount.addAndGet(count);


        if (context.getComponent().getType() == Component.Type.PROJECT) {
            System.out.println("Total issues from energy plugin: " + totalIssuesCount.get());
            context.addMeasure(ISSUES_COUNT.key(), (double) totalIssuesCount.getAndSet(0));
        }
    }
}

Here’s an example of how many smells I really have and what the metric says:
1 - 1 add 1
2 - 2 add 1
3 - 3 remove 1
2 - 3 do nothing
2 - 2 remove one
1 - 2 add one
2 - 3 do nothing
2 - 2

Especially the second last case (2 - 3) is confusing.
I know that the problem is not the totalIssuesCount, because the plugin prints the same number of smell keys (see code).
Why is the metric not up to date?
Thank you for your help!

Hi,

At a guess, this is an order-of-operations question. It sounds like your metrics are being tallied before the new issues are stored, which would be why you’re getting old counts.

I’m not sure what’s missing, but you probably want to take a look at the other issue-related metrics. E.G.

On a side note, why is this metric a Metric.ValueType.FLOAT?

 
Ann