2011-03-15 10 views
5

Spring'i slf4j ve hazırda bekletme ile kullanıyoruz, istisnaları ve hataları otomatik olarak kaydetmenin bir yolunu bulmaya çalışıyorum (örneğin her bir hata ayıklayıcısının örneğini başlatmadan), böylece herhangi bir hata veya istisna atılabilir. ve ayrıca Yay - slf4J: hataları ve istisnaları otomatik olarak nasıl kaydederim?

Ben yönlerini bunun için & önleyicilerin kullanımı hakkında çok kısa bir not okumak, günlükte sınıf ve yöntem adı almak, bu nedenle, bu uygulamaya bazı ayrıntılı şekilde

Saygılarımızla, beni sağlayabilir

+0

Bu, bir yığın izinden zaten sahip olmadığınız şey ne başarır? İstisnai bir şekilde günlüğe kaydetmeyi ve yutmayı planlıyorsanız, bu bana oldukça kötü bir fikir gibi geliyor. –

cevap

10

bir istisna durumu şöyle olabilir:

@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; 
    } 
    } 
} 

bahar 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> 

DÜZENLEME:

sen logger sarılmış fasulye adına oturum istiyorsanız, tabii ki yapabilirdi:

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

veya eğer

gerçek (potansiyel olarak proksiye/otomatik olarak oluşturulan tip) yerine bu yöntemin beyan sınıfını tercih edersiniz:

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

Dürüst olmak gerekirse, LoggerFactory.getLogger (..) öğesini her seferinde çağırmanın performans sonuçlarını tahmin edemiyorum. İstisnalar istisna (yani nadir) olduğu için çok kötü olmamalı.

+0

Cevabınız son derece açıktır, ancak logger'ın sınıf adıyla değil, çağrı sınıfı adıyla oturum açmasını istesem ne olur? –

+0

@Amr bkz. "DÜZENLEME:" – sfussenegger

+0

Cevabınız sadece daha iyi ve daha iyiye gidiyor, aynı zamanda da düşündüğüm performans sorunundan da bahsetmiştiniz, çok teşekkür ederim –

0

Saf Aspect J ile (daha çok yay ile yönetilen fasulye için kullanabilirsiniz). Bu excample, bir hizmet yöntemiyle "iade edilen" tüm istisnaları günlüğe kaydeder. Ancak, diğer yöntemlerle de eşleştiği noktayı değiştirebilirsiniz.

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);   
    } 
} 

Bu JUnit için yazılmıştır, ancak bunu adapte easely.