Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate Spring Job execution time

I have this very basic example of Spring Job.

@Scheduled(fixedRate = 90000)
    public void myScheduler() throws Exception {

        // Print here execution time into console and save into DB
    }

I have to do some very heavy calculations. Is there a way to calculate total execution time? There is a solution with listener, but I would like to do it inside the job because I want to do it in the Job implementation code.

like image 327
Peter Penzov Avatar asked Apr 15 '19 00:04

Peter Penzov


4 Answers

You can use Spring Framework's StopWatch to calculate the execution time. For multiple tasks also you can use stopwatch.

    StopWatch stopWatch = new StopWatch("StopWatchDemo");
    StopWatchDemo stopWatchDemo = new StopWatchDemo();

    stopWatch.start("StopWatchTask1");
       stopWatchDemo.performTask1();
    stopWatch.stop();

    stopWatch.start("StopWatchTask2");
        stopWatchDemo.performTask2();
    stopWatch.stop();

To get total execution time for all tasks(here task1 and task2)

    System.out.println("StopWatchDemo tasks took total: " + stopWatch.getTotalTimeSeconds() + " seconds");

To get task wise execution time

for(TaskInfo taskInfo :stopWatch.getTaskInfo()) {
    System.out.println(taskInfo.getTaskName()+"-"+taskInfo.getTimeSeconds()+" secs");
}
like image 124
prasadg Avatar answered Oct 13 '22 00:10

prasadg


Can be nicely done using @Aspect

First, add to your pom.xml:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Second, make sure that your class has @Component and @EnableScheduling.

Finally, create an Aspect class for Spring's Scheduled annotation

@Aspect
@Component
public class TimeScheduler {

    @Around("@annotation(org.springframework.scheduling.annotation.Scheduled)")
    public void timeScheduledMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("starting stopwatch");
        Object result = null;
        StopWatch watch = new StopWatch();
        try {
            watch.start();
            result = joinPoint.proceed();
        } finally {
            watch.stop();
            long executionTime = watch.getLastTaskTimeMillis();
            String className = joinPoint.getTarget().getClass().getSimpleName();
            String methodName = joinPoint.getSignature().getName();

            // print to log/console all the details you need: Time took, 
            // method name, class name etc...
            System.out.println("Time took: [" + executionTime + "] ms");
            System.out.println("Class: " + className);
            System.out.println("Method: " + methodName);

           // db.save(executionTime)
        }
    }
} 

Notice that in this way the executionTime time needs to be persisted from the Aspect class, as a method with @Scheduled can not get any arguments to be later saved.

like image 9
Stempler Avatar answered Oct 23 '22 11:10

Stempler


If your project/app is light, you can just put some:

long startTime = System.getCurrentTimeInMillis();
// whatever long processing here
long endTime = System.getCurrentTimeInMillis();
long processingTime = endTime - startTime;
// do print 
// do store to DB

However, if your project/app is big (i.e. lots of Schedulers), you may want to inject before/after aspects (also called point-cuts) to them.

Refer to this Stackoverflow answer.

like image 4
Edward Aung Avatar answered Oct 23 '22 09:10

Edward Aung


Instant begin = Instant.now();
// do whatever...    
Instant end= Instant.now();
long delta = Duration.between(begin, end).toMillis();

Instant class requires Java8

like image 3
Rao Pathangi Avatar answered Oct 23 '22 10:10

Rao Pathangi