元のアイデア: コントローラーが例外をスローすると、スタックトレースのみが利用可能ですが、それを引き起こしたパラメーターは利用できません。アイデアは、grails コントローラー、サービス、およびスレッドのその他の関心のあるポイント (POI) をラップするロギング アスペクトを配置することです。例外が発生した場合は、スタック トレースだけでなく、すべての POI からのパラメーターをログに記録します。注: クロージャーではなく、アクション (grails 2.0 以降) のメソッドを使用します。
行われたこと: 特定のアノテーションが適用されたすべての呼び出しをラップし、呼び出しパラメーターを ThreadLocal 変数に収集するアスペクト周辺。呼び出しの最後に、それがエラーであったかどうかをチェックし、それからすべての呼び出しチェーンを特定のロガーに記録します。サービスで問題なく動作しています。サービスが他のサービスを呼び出すときに組み合わせを試してみましたが、完璧に動作します。
問題: コントローラにそのようなアスペクトを適用すると失敗します。エラーは、メソッドが実際には存在するのにメソッドが見つからない (404 エラーが返される) ことを示しています (そのようなアスペクトなしでコントローラーで同じ要求を実行しても問題ありません)。
以下のようなアスペクト(簡易版)を持つ:
@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;
}
}
およびコントローラーのような: @ThreadLoggerMarker class MainController {
MainService mainService
def dummyAction( Boolean fail ){
try{
render( text:mainService.dummyAction( fail ) )
}finally{
println( ThreadLoggerHelper.prettyPrintCurrentThreadCallTrace() );
}
}
}
コントローラーを呼び出すと、次のようになります (パッケージ名はスキップされます)。
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([])
コマンド オブジェクトを含むすべてのパラメータを使用して、dummyAction の呼び出しをインターセプトするにはどうすればよいですか?