MeetJoeBlack
MeetJoeBlack

Reputation: 2924

java measure method invocation rate

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.

Upvotes: 0

Views: 1744

Answers (1)

Mark Bramnik
Mark Bramnik

Reputation: 42501

There are metering libraries that can provide the rate measurement capabilities.

Here are two of them:

Dropwizard metrics

Micrometer

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
}

Upvotes: 2

Related Questions