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.
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");
}
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.
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.
Instant begin = Instant.now();
// do whatever...
Instant end= Instant.now();
long delta = Duration.between(begin, end).toMillis();
Instant class requires Java8
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With