AOP Solution to Log Performances

Necmi Kılıç
2 min readApr 28, 2020

--

AOP stands for Aspect-Oriented Programming. As you guess, it is a design principle and implemented by Spring framework.

AOP helps us to centralize common tasks such as logging, authentication and transaction management. It accomplishes it by acting like a “interceptor”. Its structure consists of Aspect, point cuts, join points and advises.

Assume that you have an application that includes many SOAP or Rest services. You collected your end point classes under package x.y.z.endpoint.

@Endpoint
public class CustomerAddress {
@Autowired
private CustomerService customerService;
@PayloadRoot(namespace = "http://domain.com.tr/app/schema",
localPart = "GetCustomerAddressRequest")
public @ResponsePayload GetCustomerAddressResponse
handleCustomerAddressRequest(
@RequestPayload GetCustomerAddressRequest request,
MessageContext messageContext) {
return customerService.handleCustomerAddressRequest(request);
}
}

@Endpoint
public class Invoice {
@Autowired
private InvoiceService invoiceService;
@PayloadRoot(namespace = "http://domain.com.tr/app/schema",
localPart = "GetInvoiceRequest")
public @ResponsePayload GetInvoiceResponse handleInvoiceRequest(
@RequestPayload GetInvoiceRequest request, MessageContext messageContext) {
return invoiceService.handleInvoiceRequest(request);
}
}

You want to track performances of these services by logging their execution time. The first solution to accomplish it is adding start and end time code and log the duration:

long startTime = System.nanoTime();
//your business codes
long endTime = System.nanoTime();
final long duration = (endTime — startTime)/1000000;
logger.info(serviceName + “:” + duration + “ms”);

You have to add this coding block to each service. If we consider that you have hundreds services, it means a lot of copy-paste boilerplate code… It is not a practice of “clean coding”.

AOP offers a clean solution to prevent you boilerplate copy-paste codes. All you need to do is creating an Aspect class and manage the point cuts and join points.

A join point is a step of the program execution, such as the execution of a method or the handling of an exception. A pointcut is a predicate that matches the join points. Because we manage all our end point services in the package x.y.x.endpoint, we can use it as a condition for the point cut. execution means, it runs when the method executes. Here is the final code example to log performance of all services under package x.y.z.endpoint:

@Aspect
@Component
public class PerformanceLogger { private static Logger logger = Logger.getLogger("logger"); @Pointcut("execution(* x.y.z.endpoint.*.*(..)) && args(..,
messageContext)")
private void executeMethodCallInService(MessageContext
messageContext) {}
@Around("executeMethodCallInService(messageContext)")
public Object trackServiceMethods(ProceedingJoinPoint joinPoint,
MessageContext messageContext) throws Throwable {
final String fullyQualifiedMethodName =
joinPoint.getSignature().getDeclaringType().getSimpleName() +
"#" + joinPoint.getSignature().getName();
final long endTime;
long startTime = 0;
Object returnValue = null;
startTime = System.nanoTime();
returnValue = joinPoint.proceed(); endTime = System.nanoTime();
final long duration = (endTime - startTime) / 1000000;
logger.info( fullyQualifiedMethodName + ":" + duration + "ms"); return returnValue;
}
}

--

--

Necmi Kılıç
Necmi Kılıç

No responses yet