2011-03-15 17 views
5

私たちはslf4jでSpringを使用しており、hibernateを使用しています。例外やエラーを自動的に(つまり各クラスでデバッガのインスタンスを起動することなく)記録する方法を見つけようとしています。そしてまた、私は側面このため&インターセプタの使用方法についての非常に短いメモを読んで、あなたがこれを実装するためにいくつかの詳細な方法を私に提供することができ、Spring - slf4J:エラーと例外を自動的に記録する方法は?

よろしく、

、ログに

のクラスとメソッド名を取得

+0

これは、スタックトレースから得られたものではないことは何ですか?ロギングを計画し、側面から例外を飲み込むことを考えているなら、それは私にとってかなり悪い考えです。 –

答えて

10

例外の部分は次のようになります。

@Aspect 
public class ExceptionAspect { 

    private static final Logger log = LoggerFactory.getLogger(ExceptionAspect.class); 

    public Object handle(ProceedingJoinPoint pjp) throws Throwable { 
    try { 
     return pjp.proceed(); 
    } catch (Throwable t) { 
     // so something with t: log, wrap, return default, ... 
     log.warn("invocation of " + pjp.getSignature().toLongString() + " failed", t); 
     // I hate logging and re-raising, but let's do it for the sake of this example 
     throw t; 
    } 
    } 
} 

春confに:

<!-- log exceptions for any method call to any object in a package called 'svc' --> 
<bean class="org.example.aspects.ExceptionAspect" name="exceptionAspect" /> 
<aop:config> 
    <aop:aspect ref="exceptionAspect"> 
    <aop:around method="handle" pointcut="execution(* org.example..svc..*.*(..))" /> 
    </aop:aspect> 
</aop:config> 

EDIT:

あなたはロガーが包まれたBeanのかわりにログオンしたい場合、あなたはもちろん行うことができます:

LoggerFactory.getLogger(pjp.getTarget().getClass()).warn("damn!"); 

場合や、実際には(潜在的にプロキシされた/自動生成されるタイプの)このメソッドの宣言クラスを優先します:

LoggerFactory.getLogger(pjp.getSignature().getDeclaringType()).warn("damn!"); 

正直なところ、毎回LoggerFactory.getLogger(..)を呼び出すことによるパフォーマンスの影響を評価することはできません。とにかく例外は例外的です(つまり、まれです)ので、あまりにも悪くはないはずです。

+0

あなたの答えはきわめてはっきりしていますが、私のアスペクトクラスの名前ではなく、呼び出し側のクラス名でロガーに記録させたいのですが? –

+0

@Amr "編集:" – sfussenegger

+0

あなたの答えはちょうど良くなってきています。あなたもまた考えているパフォーマンスの問題について言及しました、ありがとう –

0

純粋なアスペクトJ(これは、春の管理Beanにも使用できます)。 このexcampleは、サービスメソッドによって "返された"すべての例外をログに記録します。しかし、他のメソッドにもマッチするポイントカットを変更することができます。

package test.infrastructure.exception; 

import java.util.Arrays; 

import org.apache.log4j.*; 
import org.aspectj.lang.Signature; 
import org.springframework.stereotype.Service; 

/** Exception logger*/ 
public aspect AspectJExceptionLoggerAspect { 

    /** The name of the used logger. */ 
    public final static String LOGGER_NAME = "test.infrastructure.exception.EXCEPTION_LOGGER"; 

    /** Logger used to log messages. */ 
    private static final Logger LOGGER = Logger.getLogger(LOGGER_NAME); 

    AspectJExceptionLoggerAspect() { 
    } 

    /** 
    * Pointcut for all service methods. 
    * 
    * Service methods are determined by two constraints: 
    * <ul> 
    * <li>they are public</li> 
    * <li>the are located in a class of name *SericeImpl within (implement an interface) 
    * {@link test.service} package</li> 
    * <li>they are located within a class with an {@link Service} annotation</li> 
    * </ul> 
    */ 
    pointcut serviceFunction() 
     : (execution(public * test.Service.*.*ServiceImpl.*(..))) 
     && (within(@Service *)); 

    /** Log exceptions thrown from service functions. */ 
    after() throwing(Throwable ex) : serviceFunction() { 
     Signature sig = thisJoinPointStaticPart.getSignature(); 
     Object[] args = thisJoinPoint.getArgs(); 

     String location = sig.getDeclaringTypeName() + '.' + sig.getName() + ", args=" + Arrays.toString(args); 
     LOGGER.warn("exception within " + location, ex);   
    } 
} 

それはJUnitのために書かれていますが、それを適応させるeaselyすることができます。

関連する問題