Original idea: When controller throws an exception only stacktrace is available, but not a parameters that caused it. Idea is to put a logging aspect that wraps grails controllers, services and some other points of interest (POI) for the thread, and in case of exception it logs not only stacktrace but parameters from all POI. Note: using methods for actions (since grails 2.0) not a closures.
What was done: Around aspect that wraps all calls with specific annotation applied and collects call parameters into ThreadLocal variable. In the call end it checks if it was an error and it it was, then it logs all call chain in specific logger. It is working fine with services, I tried combinations when service calls other service, and it works perfect.
Problem: When applying such aspect on controller it fails. Error states that no method can be found (404 error is returned) while it is really there (running the same request on controller without such aspect works fine).
Having aspect (simplified version) like below:
@Pointcut("@within(ThreadLoggerMarker)")
public void threadLoggerMarker(){}
@Around("threadLoggerMarker()")
public Object aroundMarker( ProceedingJoinPoint pjs )
throws Throwable
{
String beanName = pjs.signature.declaringTypeName;
String methodName = pjs.signature.name;
Object[] methodParams = pjs.args;
try{
System.out.println( "Calling ${beanName}.${methodName}(${methodParams})" );
return pjs.proceed();
}catch( Exception ex ){
System.out.println( "Got exception ${ex}" );
throw ex;
}
}
and controller like: @ThreadLoggerMarker class MainController {
MainService mainService
def dummyAction( Boolean fail ){
try{
render( text:mainService.dummyAction( fail ) )
}finally{
println( ThreadLoggerHelper.prettyPrintCurrentThreadCallTrace() );
}
}
}
Calling controller results in (package name skipped):
Calling MainController.getMetaClass([])
Calling MainController.getProperty([dummyAction])
Got exception groovy.lang.MissingPropertyException: No such property: dummyAction for class: MainController
Calling MainController.getProperty([params])
Calling MainController.getProperty([errors])
Calling MainController.getMetaClass([])
How can I intercept call for dummyAction with all parameters including command objects if there are such?