Logging request and response for Spring mvc Service - spring

hi All , i Have to log all the request , response , Exception ,
Errors for my Spring services. i had searched about the
interceptors , filters , logging filters , Spring interceptors :
HandlerInterceptorAdapter logger filters :
AbstractRequestLoggingFilter.java and its sub classes
(http://www.javawebdevelop.com/1704067/),
CommonsRequestLoggingFilter.java filters : LoggerFilter.
can any body its difference, and the best approach to do so i am
confused or i need to find out the third party library to do this
?..

I used AOP for something similar in one project. I had to write a class like this:
#Component
#Aspect
public class RequestMonitor {
private static final Logger logger = LoggerFactory.getLogger(RequestMonitor.class);
#Around("#annotation(org.example.ToBeLogged)")
public Object wrap(ProceedingJoinPoint pjp) throws Throwable {
logger.info("Before controller method " + pjp.getSignature().getName() + ". Thread " + Thread.currentThread().getName());
Object retVal = pjp.proceed();
logger.info("Controller method " + pjp.getSignature().getName() + " execution successful");
return retVal;
}
}

Log4j is a java based logging utility with easy integration with Spring MVC. Log4j comes with different logging levels to allow for appropriate logging in correspondence to the development environment.
Log4j 2 is the successor to log4j and has better performance as compared to its predecessor.
Kindly refer the following link for an integration of spring MVC + Log4j
http://www.codejava.net/frameworks/spring/how-to-use-log4j-in-spring-mvc
Edit: As mentioned in comment , PFB the code for logging both request and response.
#Aspect
#Component
public class ResponseLoggerAspect {
private static final Logger logger = Logger.getLogger("requestResponseLogger");
ExclusionStrategy excludeJsonAnnotation = new JsonIgnoreAnnotationExclusionStrategy();
Gson gson = new GsonBuilder().setExclusionStrategies(excludeJsonAnnotation).create();
#Pointcut("within(#org.springframework.stereotype.Controller *)")
public void controller() {}
#Pointcut("execution(* *(..))")
public void method() {}
#Pointcut("execution(#com.company.annotation.AddLog * *(..))")
public void Loggable() {}
//This will be caught for only those controller method where #AddLog annotation is written
#Before("Loggable()")
public void printRequestLog(JoinPoint joinPoint) {
try {
Object[] argsList = joinPoint.getArgs();
String str = "[";
for(Object arg : argsList) {
if(arg instanceof Object[]) {
str += Arrays.toString((Object[])arg) + ", ";
} else {
str += String.valueOf(arg) + ", ";
}
}
str += "]";
logger.info("Request args for " + joinPoint.getSignature().getName() + " are : " + str);
} catch(Exception ex) {
logger.info("Unable to log request args", ex);
}
}
//This will be called for all controller methods after returning
#AfterReturning(pointcut = "controller() && method()", returning="result")
public void afterReturning(JoinPoint joinPoint , Object result) {
long start = System.nanoTime();
try {
logger.info("Response sent by " + joinPoint.getSignature().getName() + " are : " + gson.toJson(result));
} catch(Exception ex) {
logger.error("Returned result cant be converted in JSON " , ex);
}
long end = System.nanoTime();
logger.info("elapsed time : " + (end - start));
}
}

Related

Test Fallback method using sping-cloud-starter-circuitbreaker-resilience4j

public String getAlbumList() {
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitbreaker");
String url = "http://localhost:1234/not-real";
return circuitBreaker.run(() -> restTemplate.getForObject(url, String.class),
throwable -> getDefaultAlbumList());
}
Assume this is my code and "getDefaultAlbumList()" is returning some string "ABCD", and let say my "restTemplate.getForObject(url, String.class)" is going to call some URL which may take more than 5 second, now point is
I want to test that fallback method, how do i test it, how do i mock so that my controller return fallback response.
Thanks
I suppose that you are trying out the example from here: Quick Guide to Spring Cloud Circuit Breaker. So, I copied their service and I introduced a method to pass a null URL. Then I created a test in a spring boot project that verifies if the string value that returns is the fallback string.
#Service
public class AlbumService {
private RestTemplate restTemplate = new RestTemplate();
#Autowired
private CircuitBreakerFactory circuitBreakerFactory;
public String getAlbumList() {
return getAlbumList("https://jsonplaceholder.typicode.com/albums");
}
public String getAlbumList(String url) {
CircuitBreaker circuitBreaker = circuitBreakerFactory.create("circuitbreaker");
return circuitBreaker.run(() -> restTemplate.getForObject(url, String.class),
throwable -> getDefaultAlbumList());
}
// fallback method that reads a default json file
private String getDefaultAlbumList() {
try {
return new String(Files.readAllBytes(
Paths.get(getClass().getClassLoader().getResource("data/fallback-album-list.json").toURI())
));
} catch (Exception e) {
LOGGER.error("error occurred while reading the file", e);
}
return null;
}
}
Then the unit test should test the fallback default json string.
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE, properties = {"server.port=0"})
#ExtendWith(SpringExtension.class)
#DirtiesContext
class AlbumServiceTest {
#Autowired
AlbumService albumService;
#Test
void getAlbumListFallBack() {
String result = albumService.getAlbumList(null);
assertNotNull(result);
assertTrue(result.length() > 0);
assertEquals(
"[\n" +
" {\n" +
" \"userId\": 1,\n" +
" \"id\": 1,\n" +
" \"title\": \"quidem molestiae enim\"\n" +
" },\n" +
" {\n" +
" \"userId\": 1,\n" +
" \"id\": 2,\n" +
" \"title\": \"sunt qui excepturi placeat culpa\"\n" +
" }\n" +
"]",
result);
}
}

How to write the Junit Mockito code for this Aspect class for maximum code coverage

Could someone please help me out in writing Junit for this piece of code and provide resources to learn the same. I have been trying to figure out from multiple resources but couldn't find anything. I need to mock the pointcuts and methods which are invoked within the pointcut. Is unit testing possible for this using Mockito
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.sample.api.rest.account.AccountResource;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.CustomLog;
import lombok.extern.slf4j.slf4j;
#Aspect
#CustomLog
public class sample {
ObjectMapper mapper = new ObjectMapper();
long startTimeController = 0L;
long endTimeController = 0L;
#Pointcut("within(com.sample.api.rest.account. .) || "
+ "within(com.sample.api.rest.metadata..') ")
public void entryController() {}
#Pointcut("within(com. sample.api.rest.user..*)")
public void entryControllerUser() {}
#Pointcut("within(com.sample.api.service. .*)")
public void entryService() {}
#Pointcut("within(com. sample.cmo.repositories..*)")
public void entryDAO() {}
#Before("entryController()")
public void beforeOtherControllerCall(JoinPoint jp) throws JsonProcessingException {
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
Object[] arguments = jp.getArgs();
log.info(className + " Method : " + methodName + " Arguments passed : " +
mapper.writeValueAsString(arguments));
startTimeController = System.currentTimeMillis();
}
#Before("entryControllerUser()")
public void beforeUserControllerCall(JoinPoint jp) throws JsonProcessingException {
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
log.info(className + " Method : " + methodName);
startTimeController = System.currentTimeMillis();
}
#After("entryController() || entryControlleruser()")
public void afterControllerCall(JoinPoint jp) throws JsonProcessingException {
endTimeController = System.currentTimeMillis();
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
log.info(className + " Method : " + methodName + " Values returned :");
if (endTimeController != 0) {
log.info("Time consumed in " + className + " " + methodName + " call is "
+ (endTimeController - startTimeController) + "ms");
}
}
#Around("entryService()")
public Object executionTimeService(ProceedingJoinPoint pjp) throws Throwable {
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
Object[] arguments = pjp.getArgs();
log.info(className + " Method: " + methodName + " Arguments passed :" +
mapper.writeValueAsString(arguments));
long startTime = System.currentTimeMillis();
Object obj = pip.proceed();
long endTime = System.currentTimeMillis();
log.info(className + " Method : " + methodName + " Execution time: " + (endTime -
startTime) + "ms");
log.info(className + " Method : " + methodName + " Response received : " +
mapper.writeValueAsString(obj));
return obj;
}
#Around("entryDAO()")
public Object executionTimeDAO(ProceedingJoinPoint pjp ) throws Throwable {
String methodName pjp.getSignature().getName();
String className pjp.getTarget().getClass().toString();
Object[] arguments = pjp.getArgs();
log.info(className+" Method : "+methodName+" Arguments passed :"
+mapper.writeValueAsString(arguments) );
long startTime = System.currentTimeMillis();
Object obj = pip.proceed();
long endTime = System.currentTimeMillis();
log.info(className+" method : " + methodName+" Execution time: "
+(endTime-start Time)+"ms" );
log.info(className+" Method: "+methodName+" Response received : "+
mapper.writeValueAsString(obj));
return obj;
}
}
Here is the sample of what I have tried with
#Test
public void testBeforeOtherControllerCall() throws Throwable{
JoinPoint joinPoint = mock(JoinPoint.class);
AspectLogging logging = mock(AspectLogging.class);
String[] args = {"arg1", "arg2"};
Object[] obj args)
Signature signature = mock (Signature.class);
when(joinPoint.getSignature().thenReturn(signature);
when(signature.getName().thenReturn("MethodName");
Object object = mock(Object.class);
when(joinPoint.getTarget().thenReturn(object);
when(object.getClass().thenReturn(objectClass);
when(joinPoint.getArgs().thenReturn(obj);
logging.beforeOtherControllerCali(joinPoint);
verify(joinPoint, times (1)).getSignature().getName().equals("MethodName");
}
Preface
When trying to recreate your situation, I had to
guess about which libraries and versions you use,
replace the Lombok logging annotation by a regularly created SLF4J logger, because, as the AspectJ compiler tells you in a warning message, Lombok's byte code modifications do not work with the AspectJ compiler: java: You aren't using a compiler supported by lombok, so lombok will not work and has been disabled. (...) Lombok supports: sun/apple javac 1.6, ECJ. When using Spring AOP instead, it probably works with Lombok, because there you are simply using the normal Java compiler. I however tested in native AspectJ.
fix many syntax errors in your aspect and test Java code as well as several syntax errors in your aspect pointcuts. The classes did not even compile and the aspect cannot have done anything meaningful with faulty pointcuts. If you modify original code in order to create a stand-alone example, please test before posting it. You should have a little bit more pride as a developer when presenting your work publicly. This was your free shot, because you are new on SO, but next time I will just close the question.
Please do read the MCVE article, try to understand it and ask better questions in the future.
Fixed aspect code
package de.scrum_master.aspect;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
#Aspect
public class LoggingAspect {
private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);
ObjectMapper mapper = new ObjectMapper();
long startTimeController = 0L;
long endTimeController = 0L;
#Pointcut("within(com.sample.api.rest.account..*) || within(com.sample.api.rest.metadata..*)")
public void entryController() {}
#Pointcut("within(com.sample.api.rest.user..*)")
public void entryControllerUser() {}
#Pointcut("within(com.sample.api.service..*)")
public void entryService() {}
#Pointcut("within(com.sample.cmo.repositories..*)")
public void entryDAO() {}
#Before("entryController()")
public void beforeOtherControllerCall(JoinPoint jp) throws JsonProcessingException {
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
Object[] arguments = jp.getArgs();
log.info(className + " Method : " + methodName + " Arguments passed : " + mapper.writeValueAsString(arguments));
startTimeController = System.currentTimeMillis();
}
#Before("entryControllerUser()")
public void beforeUserControllerCall(JoinPoint jp) throws JsonProcessingException {
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
log.info(className + " Method : " + methodName);
startTimeController = System.currentTimeMillis();
}
#After("entryController() || entryControllerUser()")
public void afterControllerCall(JoinPoint jp) throws JsonProcessingException {
endTimeController = System.currentTimeMillis();
String methodName = jp.getSignature().getName();
String className = jp.getTarget().getClass().toString();
log.info(className + " Method : " + methodName + " Values returned :");
if (endTimeController != 0) {
log.info("Time consumed in " + className + " " + methodName + " call is " + (endTimeController - startTimeController) + "ms");
}
}
#Around("entryService()")
public Object executionTimeService(ProceedingJoinPoint pjp) throws Throwable {
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
Object[] arguments = pjp.getArgs();
log.info(className + " Method: " + methodName + " Arguments passed :" + mapper.writeValueAsString(arguments));
long startTime = System.currentTimeMillis();
Object obj = pjp.proceed();
long endTime = System.currentTimeMillis();
log.info(className + " Method : " + methodName + " Execution time: " + (endTime - startTime) + "ms");
log.info(className + " Method : " + methodName + " Response received : " + mapper.writeValueAsString(obj));
return obj;
}
#Around("entryDAO()")
public Object executionTimeDAO(ProceedingJoinPoint pjp) throws Throwable {
String methodName = pjp.getSignature().getName();
String className = pjp.getTarget().getClass().toString();
Object[] arguments = pjp.getArgs();
log.info(className + " Method : " + methodName + " Arguments passed :" + mapper.writeValueAsString(arguments));
long startTime = System.currentTimeMillis();
Object obj = pjp.proceed();
long endTime = System.currentTimeMillis();
log.info(className + " method : " + methodName + " Execution time: " + (endTime - startTime) + "ms");
log.info(className + " Method: " + methodName + " Response received : " + mapper.writeValueAsString(obj));
return obj;
}
}
Fixed test
I sent you two links before in my comment, showing you how to write unit and integration tests. Why did you not do it more similar to my examples? Some things you did wrong are:
You created a mock for the aspect class under test. Why? You want to mock dependencies, not the thing you actually want to test. Like in my examples, you should instantiate the aspect normally, only inject a mock joinpoint when calling an advice method.
You cannot simply verify a chain of method calls on a corresponding chain of mock objects, but need to verify them separately. So, something like verify(joinPoint, times (1)).getSignature().getName().equals("MethodName") does not work.
You tried to stub when(object.getClass()).thenReturn(objectClass), which is unnecessary, because Object.getClass() returns something already. Furthermore, it is a final method of a JDK bootstrap class. You cannot simply mock that.
How about this?
package de.scrum_master.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
public class LoggingAspectTest {
#Test
public void testBeforeOtherControllerCall() throws Throwable {
JoinPoint joinPoint = mock(JoinPoint.class);
LoggingAspect logging = new LoggingAspect();
String[] args = { "arg1", "arg2" };
Object[] obj = args;
Signature signature = mock(Signature.class);
when(joinPoint.getSignature()).thenReturn(signature);
when(signature.getName()).thenReturn("MethodName");
Object object = mock(Object.class);
when(joinPoint.getTarget()).thenReturn(object);
when(joinPoint.getArgs()).thenReturn(obj);
logging.beforeOtherControllerCall(joinPoint);
verify(joinPoint, times(1)).getSignature();
verify(signature, times(1)).getName();
verify(joinPoint, times(1)).getTarget();
verify(joinPoint, times(1)).getArgs();
}
}
This covers the method under test and verifies the calls on the mock objects you are interested in, even though I find those verifications somewhat questionable. Do you really want to test the internals of the aspect? You should rather test for side effects or results, if any. But of course you can do it like in my example.
My IDE looks like this when running the test with coverage:

Spring WebFlux endpoint performance logger

Do you know any good practices to log Spring WebFlux controller endpoint performance to keep reactive nature? Seems the following principle wouldn't work because it will block the IO as the ProceedingJoinPoint doesn't return Publisher<> , it returns just an object
#Aspect
#Component
#Slf4j
public class LoggingAspect
{
//AOP expression for which methods shall be intercepted
#Around("execution(* com.company.service..*(..)))")
public Object profileAllMethods(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
//Get intercepted method details
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getName();
final StopWatch stopWatch = new StopWatch();
//Measure method execution time
stopWatch.start();
Object result = proceedingJoinPoint.proceed();
stopWatch.stop();
//Log method execution time
log.info("Execution time of " + className + "." + methodName + " :: " + stopWatch.getTotalTimeMillis() + " ms");
return result;
}
}
Actually as mentioned #Toerktumlare in the comments proceedingJoinPoint.proceed() returns the type of object whatever is you controller endpoint return type, so it is possible to keep reactive nature. Note .subscribeOn(Schedulers.parallel()) is optional here, that is for my back code to support parallelism. Posting the solution for this:
#Aspect
#Component
#Slf4j
public class LoggingAspect
{
//AOP expression for which methods shall be intercepted
#Around("execution(* com.company.service..*(..)))")
public Object logEndpointPerformance(ProceedingJoinPoint proceedingJoinPoint) throws Throwable
{
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
//Get intercepted method details
String className = methodSignature.getDeclaringType().getSimpleName();
String methodName = methodSignature.getName();
final StopWatch stopWatch = new StopWatch();
//Measure method execution time
stopWatch.start();
Object result = proceedingJoinPoint.proceed();
if(result instanceof Mono){
return ((Mono)result).subscribeOn(Schedulers.parallel()).flatMap(r -> {
logExecutionTime(className, methodName, stopWatch);
return Mono.just(r);
});
}
else if(result instanceof Flux){
return ((Flux<Object>)result).subscribeOn(Schedulers.parallel()).collectList().flatMapMany(r -> {
logExecutionTime(className, methodName, stopWatch);
return Flux.fromIterable(r);
});
}
else{
logExecutionTime(className, methodName, stopWatch);
return result;
}
}
private void logExecutionTime(final String className, final String methodName, final StopWatch stopWatch){
stopWatch.stop();
//Log method execution time
log.debug("[ " + stopWatch.getTotalTimeMillis() + " mls ] lasted execution of" + className + "." + methodName );
}
}

Not getting actual parameter names in Spring Boot Aspect

I am trying to add log statements before executing every method dynamically using Aspectj.
Code:
#Component
#Aspect
public class MethodLogger {
DiagnosticLogger logger = DiagnosticLogger.getLogger(getClass());
#Before("execution(* com.xyz..*.*(..))")
public void beforeMethod(JoinPoint joinPoint) throws Throwable {
System.out.println("Class******" + joinPoint.getTarget().getClass().getName());
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
System.out.println("Method******" + signature.getName());
// append args
Object[] args = joinPoint.getArgs();
String[] parameterNames = signature.getParameterNames();
if (parameterNames != null) {
for (int i = 0; i < parameterNames.length; i++) {
System.out.println("parameterNames******" + parameterNames[i] + ":" + args[i]);
}
}
}
}
Output:
Class******com.xyz.security.web.UserController
Method******forgotPassword
parameterNames******userEmail:naresh#xyz.com
Class******com.xyz.security.service.impl.UserServiceImpl
Method******forgotPassword
parameterNames******userEmail:naresh#xyz.com
Class******com.sun.proxy.$Proxy436
Method******findByUserEmail
I am able to get at controller and service level. But when comes to Spring Data JPA Repository method its not able to print.
How to get the parameter names at Repository level ?
Here an example of what I did.
By adding + sign also the classes that implement my Repository or any other of my interfaces in com.example.** are intercepted.
#Slf4j
#Component
#Aspect
public class MethodLogger {
#Before("execution(* com.example.*..*+.*(..))")
public void beforeMethod(JoinPoint joinPoint) throws Throwable {
log.info("Class******" + joinPoint.getTarget().getClass().getName());
for (Class<?> theinterface: joinPoint.getTarget().getClass().getInterfaces()) {
log.info("Interfaces******" + theinterface.getName());
}
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
log.info("Method******" + signature.getName());
Object[] args = joinPoint.getArgs();
String[] parameterNames = signature.getParameterNames();
if (parameterNames != null) {
for (int i = 0; i < parameterNames.length; i++) {
log.info("parameterNames******" + parameterNames[i] + ":" + args[i]);
}
}
}
}
Parameter names are also logged:
Class******com.sun.proxy.$Proxy87
Interfaces******com.example.demoaspectmethodlogging.control.EmployeeRepository
Interfaces******org.springframework.data.repository.Repository
Interfaces******org.springframework.transaction.interceptor.TransactionalProxy
Interfaces******org.springframework.aop.framework.Advised
Interfaces******org.springframework.core.DecoratingProxy
Method******findByName
parameterNames******name:Simon

#Around advice returning correct response but at client side response is null or undefined

I am trying to apply Around advice to my "Login.jsp" with angular js. And the problem is my controller method is check and I am applying around advice to check method but when I run my application I will get undefined as response at Login.jsp. And but the result which I had printed in my advice contains expected result.But I am not getting it on client side.
AroundAdvice.java
#Aspect #Component
public class AroundAdvice {
static Logger log = Logger.getLogger(AfterLoginAspect.class.getName());
#Around("execution(* com.admin.controller.LoginController.check(..))")
public void logWrittter(ProceedingJoinPoint jp) throws Throwable {
SimpleDateFormat date=new SimpleDateFormat();
log.info("Date Time :: " + date.format(new Date().getTime()));
Object result = jp.proceed();
System.out.println("result around");
log.info("result :: " + result);
// returns {"get Status":"home"}
}
}
LoginController.jsp
// authentication check
#RequestMapping(value = "/PostFormData", method = RequestMethod.POST)
public #ResponseBody JSONObject check(#RequestBody LoginBo login) {
System.out.println("checkCredentials::" + login.getUserName());
String username = login.getUserName();
// log.info("uswername ::"+username);
JSONObject result = new JSONObject();
String encrptedpassword = encryptdPwd.encrypt(login.getPassWord());
boolean login_status = loginService.checkCredentials(username, encrptedpassword);
// log.info("login_status ::"+login_status);
// System.out.println("staus ::"+login_status);
if (login_status == true && login.isIs_system_generated_pwd() == true) {
System.out.println("sys gen chnge pwd:: " + login.isIs_system_generated_pwd());
result.put("getStatus", "change");
// System.out.println(resultPage);
// login.setIs_system_generated_pwd(false);
} else if (login_status == true && login.isIs_system_generated_pwd() == false) {
result.put("getStatus", "home");
// System.out.println("Home paege ");
} else {
result.put("getStatus", "error");
}
System.out.println("result ::" + result);
// log.info("result ::"+resultPage);
return result;
}
Your pointcut does not match because the advice has a void return type, but your method returns a JSONObject. So maybe you want to change your advice declaration to:
#Aspect #Component
public class AroundAdvice {
static Logger log = Logger.getLogger(AfterLoginAspect.class.getName());
#Around("execution(* com.admin.controller.LoginController.check(..))")
public JSONObject logWriter(ProceedingJoinPoint jp) throws Throwable {
SimpleDateFormat date=new SimpleDateFormat();
log.info("Date Time :: " + date.format(new Date().getTime()));
JSONObject result = (JSONObject) jp.proceed();
System.out.println("result around");
log.info("result :: " + result);
return result;
}
}
Please note
public JSONObject logWriter instead of public void logWrittter,
JSONObject result = (JSONObject) jp.proceed(); instead of Object result = jp.proceed(); and
return result; instead of no return value.

Resources