[sonar-dev] How do you define and save a custom metric on a file?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
fge
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

[sonar-dev] How do you define and save a custom metric on a file?

fge
Hello,

For the recall, I wanted to collect in some way or another all the
ASTs of all files in order to compute custom checks and metrics.

After many days of looking around I have finally managed to do it by
hacking around in the SquidSensor implementation: I simply add a
further visitor to the AstScanner which simply generates a
Map<SourceCode, AstNode>.

I have another class which takes the result of this visitor, plus
information from the SquidSensor (namely, the SensorContext and a Map
associating the SourceCode to the InputFiles), I can compute my
metrics, no problem.

But I can't save them. When I try to, I get this error:

ERROR: Error during Sonar runner execution
org.sonar.runner.impl.RunnerException: Unable to execute Sonar
    at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:91)
    at org.sonar.runner.impl.BatchLauncher$1.run(BatchLauncher.java:75)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.sonar.runner.impl.BatchLauncher.doExecute(BatchLauncher.java:69)
    at org.sonar.runner.impl.BatchLauncher.execute(BatchLauncher.java:50)
    at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:102)
    at org.sonar.runner.api.Runner.execute(Runner.java:100)
    at org.sonar.runner.Main.executeTask(Main.java:70)
    at org.sonar.runner.Main.execute(Main.java:59)
    at org.sonar.runner.Main.main(Main.java:53)
Caused by: org.sonar.api.utils.SonarException: Unknown metric: DIT
    at org.sonar.batch.index.DefaultIndex.addMeasure(DefaultIndex.java:238)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:189)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:182)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:277)
    at es.litesolutions.sonar.objectscript.metrics.crossfile.ProjectWrapper.saveMetric(ProjectWrapper.java:51)
    at es.litesolutions.sonar.objectscript.metrics.crossfile.InheritanceTreeMeasurer.compute(InheritanceTreeMeasurer.java:58)
    at es.litesolutions.sonar.objectscript.ObjectScriptSquidSensor.analyse(ObjectScriptSquidSensor.java:137)
    at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:59)
    at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:51)
    at org.sonar.batch.phases.DatabaseModePhaseExecutor.execute(DatabaseModePhaseExecutor.java:120)
    at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:264)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:235)
    at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:230)
    at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:220)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.scan.ScanTask.scan(ScanTask.java:57)
    at org.sonar.batch.scan.ScanTask.execute(ScanTask.java:45)
    at org.sonar.batch.bootstrap.TaskContainer.doAfterStart(TaskContainer.java:135)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:158)
    at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:95)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
    at org.sonar.runner.batch.IsolatedLauncher.execute(IsolatedLauncher.java:48)

The line of code saving the metric is this:

public void saveMetric(final SourceCode code, final Metric metric,
    final double value)
{
    final InputFile inputFile = fileMap.get(code);
    context.saveMeasure(inputFile, new Measure(metric, value));
}


The metric is defined like this:

public final class CrossFileMetrics
{
    public static final Metric<Integer> DEPTH_INHERITANCE_TREE;

    static {
        DEPTH_INHERITANCE_TREE = new Metric.Builder("DIT",
            "Depth of Inheritance Tree", Metric.ValueType.INT)
            .create();
    }
}

and is register like this in the AstScanner:

public enum Foo
    implements MetricDef
{
    FOO,
    ;

    @Override
    public String getName()
    {
        return "DIT";
    }

    @Override
    public boolean isCalculatedMetric()
    {
        return false;
    }

    @Override
    public boolean aggregateIfThereIsAlreadyAValue()
    {
        return false;
    }

    @Override
    public boolean isThereAggregationFormula()
    {
        return false;
    }

    @Override
    public CalculatedMetricFormula getCalculatedMetricFormula()
    {
        return null;
    }
}

// ...

builder.withMetrics(Foo.FOO);

I have tried, again, to read documentation, google around etc, to no
avail; I can't get it to work.

What is happening? What should I do to make that work?

Regards,
--
Francis Galiegue, [hidden email], https://github.com/fge
JSON Schema in Java: http://json-schema-validator.herokuapp.com
Parsers in pure Java: https://github.com/fge/grappa

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: [sonar-dev] How do you define and save a custom metric on a file?

Julien HENRY
Hi Francis,

New metrics should be declared using org.sonar.api.measures.Metrics extension point.

For example:

++

Julien

2015-05-21 19:43 GMT+02:00 Francis Galiegue <[hidden email]>:
Hello,

For the recall, I wanted to collect in some way or another all the
ASTs of all files in order to compute custom checks and metrics.

After many days of looking around I have finally managed to do it by
hacking around in the SquidSensor implementation: I simply add a
further visitor to the AstScanner which simply generates a
Map<SourceCode, AstNode>.

I have another class which takes the result of this visitor, plus
information from the SquidSensor (namely, the SensorContext and a Map
associating the SourceCode to the InputFiles), I can compute my
metrics, no problem.

But I can't save them. When I try to, I get this error:

ERROR: Error during Sonar runner execution
org.sonar.runner.impl.RunnerException: Unable to execute Sonar
    at org.sonar.runner.impl.BatchLauncher$1.delegateExecution(BatchLauncher.java:91)
    at org.sonar.runner.impl.BatchLauncher$1.run(BatchLauncher.java:75)
    at java.security.AccessController.doPrivileged(Native Method)
    at org.sonar.runner.impl.BatchLauncher.doExecute(BatchLauncher.java:69)
    at org.sonar.runner.impl.BatchLauncher.execute(BatchLauncher.java:50)
    at org.sonar.runner.api.EmbeddedRunner.doExecute(EmbeddedRunner.java:102)
    at org.sonar.runner.api.Runner.execute(Runner.java:100)
    at org.sonar.runner.Main.executeTask(Main.java:70)
    at org.sonar.runner.Main.execute(Main.java:59)
    at org.sonar.runner.Main.main(Main.java:53)
Caused by: org.sonar.api.utils.SonarException: Unknown metric: DIT
    at org.sonar.batch.index.DefaultIndex.addMeasure(DefaultIndex.java:238)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:189)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:182)
    at org.sonar.batch.deprecated.DeprecatedSensorContext.saveMeasure(DeprecatedSensorContext.java:277)
    at es.litesolutions.sonar.objectscript.metrics.crossfile.ProjectWrapper.saveMetric(ProjectWrapper.java:51)
    at es.litesolutions.sonar.objectscript.metrics.crossfile.InheritanceTreeMeasurer.compute(InheritanceTreeMeasurer.java:58)
    at es.litesolutions.sonar.objectscript.ObjectScriptSquidSensor.analyse(ObjectScriptSquidSensor.java:137)
    at org.sonar.batch.phases.SensorsExecutor.executeSensor(SensorsExecutor.java:59)
    at org.sonar.batch.phases.SensorsExecutor.execute(SensorsExecutor.java:51)
    at org.sonar.batch.phases.DatabaseModePhaseExecutor.execute(DatabaseModePhaseExecutor.java:120)
    at org.sonar.batch.scan.ModuleScanContainer.doAfterStart(ModuleScanContainer.java:264)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.scan.ProjectScanContainer.scan(ProjectScanContainer.java:235)
    at org.sonar.batch.scan.ProjectScanContainer.scanRecursively(ProjectScanContainer.java:230)
    at org.sonar.batch.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:220)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.scan.ScanTask.scan(ScanTask.java:57)
    at org.sonar.batch.scan.ScanTask.execute(ScanTask.java:45)
    at org.sonar.batch.bootstrap.TaskContainer.doAfterStart(TaskContainer.java:135)
    at org.sonar.api.platform.ComponentContainer.startComponents(ComponentContainer.java:92)
    at org.sonar.api.platform.ComponentContainer.execute(ComponentContainer.java:77)
    at org.sonar.batch.bootstrap.GlobalContainer.executeTask(GlobalContainer.java:158)
    at org.sonar.batch.bootstrapper.Batch.executeTask(Batch.java:95)
    at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:67)
    at org.sonar.runner.batch.IsolatedLauncher.execute(IsolatedLauncher.java:48)

The line of code saving the metric is this:

public void saveMetric(final SourceCode code, final Metric metric,
    final double value)
{
    final InputFile inputFile = fileMap.get(code);
    context.saveMeasure(inputFile, new Measure(metric, value));
}


The metric is defined like this:

public final class CrossFileMetrics
{
    public static final Metric<Integer> DEPTH_INHERITANCE_TREE;

    static {
        DEPTH_INHERITANCE_TREE = new Metric.Builder("DIT",
            "Depth of Inheritance Tree", Metric.ValueType.INT)
            .create();
    }
}

and is register like this in the AstScanner:

public enum Foo
    implements MetricDef
{
    FOO,
    ;

    @Override
    public String getName()
    {
        return "DIT";
    }

    @Override
    public boolean isCalculatedMetric()
    {
        return false;
    }

    @Override
    public boolean aggregateIfThereIsAlreadyAValue()
    {
        return false;
    }

    @Override
    public boolean isThereAggregationFormula()
    {
        return false;
    }

    @Override
    public CalculatedMetricFormula getCalculatedMetricFormula()
    {
        return null;
    }
}

// ...

builder.withMetrics(Foo.FOO);

I have tried, again, to read documentation, google around etc, to no
avail; I can't get it to work.

What is happening? What should I do to make that work?

Regards,
--
Francis Galiegue, [hidden email], https://github.com/fge
JSON Schema in Java: http://json-schema-validator.herokuapp.com
Parsers in pure Java: https://github.com/fge/grappa

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email



Loading...