Search code examples
jmxspring-boot-actuatorcodahale-metrics

Metric name already exists - Metric registry


I am using the metric registry to log the metric into jmx. I use the below code

protected void submitMetric(String metricName, long value) {

                mr.register(metricName, new Gauge<Long>() {

                    @Override
                    public Long getValue() {
                        return value;
                    }

                });
}

It works fine for the first time. If I try to do again I get the error A metric named ***** already exist. But I would like to log the value for the same metric for every request I send to the controller so that I can visualize in Grafana.

Is there any way i can log the values for the same metric name for every request?

Also how to check all the data point logged for every 1 minute. Should we sum the values for every minute? I have the below in metrics.xml

<publish name="****">
            <delay>60</delay>
            <unit>SECONDS</unit>
        </publish>

Solution

  • Normally, you want to create the gauge and register it once, say by creating a gauge from an AtomicLong. Then you just update the gauge's value by setting the value on the AtomicLong. In this case, since you want to access the gauge by name, you could keep a map of AtomicLongs and register the gauge once when the map is updated with a new gauge:

    final Map<String, AtomicLong> gauges = new ConcurrentHashMap<>();
    
    protected void submitMetric(String metricName, long value) {
        // If the gauge does not exist, create and register it
        gauges.computeIfAbsent(metricName, k -> {
            AtomicLong g = new AtomicLong();
            mr.register(k, new Gauge<Long>() {
                @Override
                public Long getValue() {
                    return g.get();
                }
            });         
            return g;
        }).set(value); // Then set the value
        // Counters can be retrieved by name
        mr.counter(metricName + "Counter").inc(value);
        // Meters can be retrieved by name
        mr.meter(metricName + "Meter").mark(value);
    }