I want to calculate and print method invocation rate, let's say I have the following method that is called on every consumed message (from Kafka):
public class Consumer {
public void run() {
while (true) {
ConsumerRecords<String> recs = consumer.poll();
for(ConsumerRecord record: recs) {
parseMessageToDB(record.getValue());
}
}
}
public void parseMessageToDB(String message) {
// message parsing logic..
}
}
My goal here is to calculate #parseMessageToDB method invocations per second to know the speed with that my application can consume events from Kafka.
I tried to use RateLimiter from Guava but it doesn't return the current invocation rate.
Right now I ended up with the following solution where I simply calculate the number of consumed messages in 15sec and simply reset it to zero after logging.
This calculation is not very accurate since I rely on the timer intervals and also there is a possibility to take(or reset) values from another 15sec window, but this gives me at least some picture:
public class Consumer {
private final Timer timer = new Timer();
private final AtomicLong parsedEvents = new AtomicLong();
private static final int CONSUMER_TIMER_RATE_SEC = 15;
public Consumer () {
timer.schedule(new TimerTask() {
@Override
public void run() {
logEventsParsingRate();
}
}, 0, CONSUMER_TIMER_RATE_SEC*1000);
}
public void run() {
while (true) {
ConsumerRecords<String> recs = consumer.poll();
for(ConsumerRecord record: recs) {
parseMessageToDB(record.getValue());
}
parsedEvents.addAndGet(recs.count());
}
}
private void logEventsParsingRate() {
logger.info("Consumer events consuming rate per sec: " +
handledEvents.getAndSet(0)/CONSUMER_TIMER_RATE_SEC);
}
}
So I'm still looking for any other more accurate solutions.
There are metering libraries that can provide the rate measurement capabilities.
Here are two of them:
Both work in a similar way to some descent - keep in memory an object that has all the required information.
Usually, these frameworks are used in conjunction with metrics persistence servers like Prometheus, Influx DB, Graphite, etc + some UI tool that allows easy view and analysis of the values (like Grafana).
But even in a "stadalone" mode they can report the gathered information to Log files or JMX for instance
For example, in Dropwizard, there is a "Meter" primitive that can be used like this:
// somewhere globally defined
private final MetricRegistry metrics = new MetricRegistry();
private final Meter requests = metrics.meter("requests");
// the method to be metered
public void run() {
requests.mark();
// do stuff
}