I am trying to publish number of events my App is processing. This is the code I have at the receiving end:
public void process(List<String> batch) {
logger.info ("Processing batch of size " + batch.size())
metrics.incrementCounter(MetricsType.CONSUMER_TOTAL_PROCESSED, batch.size)
}
The class Metrics is:
public class Metrics {
private static final Map<MetricsType, Counter> COUNTER_MAP = new ConcurrentHashMap<>();
public Metrics(
@Autowired MeterRegistry meterRegistry
) {
COUNTER_MAP.put(
MetricsType.CONSUMER_TOTAL_PROCESSED,
Counter.builder("CONSUMER_TOTAL_PROCESSED").register(meterRegistry)
);
COUNTER_MAP.put(
MetricsType.CONSUMER_DUPLICATE_PROCESSED,
Counter.builder("CONSUMER_DUPLICATE_PROCESSED").register(meterRegistry)
);
}
public void increment(MetricsType metricsType, int size) {
COUNTER_MAP.get(metricsType).increment(size);
}
}
The enum MetricsType
contains all type of counters.
The process
method is be invoked by 16 threads at any time. The issue I am facing is the logger which prints the count and the total count reported in grafana are way off.
Do I have to synchonize everytime I am incrementing the counter?
Edit - What I mean by the counts are off is, if there are two logs with size 200, then grafana should report total counter 400. I am validating this by taking a time range of 2 hours, I extract all the sizes from logs and add them.
If you stumble upon this and see a difference between two sources please check what is your maximum number of data points in Grafana, that was the actual issue why I thought counters may not be threadsafe.