2012-11-13 9 views
9

Mam klasy z połączeń baz danych, a ja generalnie chcą rejestrować każde metody zwanej (z argumentami) w tej klasie z log4j:Jak mogę się zalogować każdą metodę zwaną klasą automatycznie z log4j

logger.debug("foo(id="+id+") initiated"); 

Czy można to zrobić automatycznie? Może za pomocą jakiejś adnotacji na początku każdej metody zamiast pisać każdy pojedynczy logger.debug?

Dziś muszę aktualizować login.debug przy każdej zmianie argumentów lub nazwy metody.

+0

AOP może warto spróbować. – Nishant

Odpowiedz

6

Spróbuj @Loggable adnotacji i aspekt AspectJ z jcabi-aspects (jestem programistą):

@Loggable(Loggable.INFO) 
public String load(URL url) { 
    return url.openConnection().getContent(); 
} 

Wszystkie wywołania metod są rejestrowane przez slf4j.

5

Jeśli masz interfejsy deklarujące metody, do których chcesz rejestrować połączenia, możesz użyć standardowego interfejsu API Proxy, aby osiągnąć to, co chcesz.

Proxy API pozwoliłoby na owinięcie rzeczywistej implementacji w nową klasę proxy, która rejestrowałaby połączenie i przekazywanie wywołania do implementacji. Trzeba tylko zaimplementować jeden InvocationHandler, który wykonuje rejestrowanie i przekazywanie.

Na przykład

interface Calculator { 
    int add(int a, int b); 
} 

class CalculatorImpl implements Calculator { 
    @Override public int add(int a, int b) { return a+b; } 
} 

class LoggingInvocationHandler implements InvocationHandler { 
    private final Object delegate; 
    public LoggingInvocationHandler(final Object delegate) { 
    this.delegate = delegate; 
    } 
    @Override invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    System.out.println("method: " + method + ", args: " + args); 
    return method.invoke(delegate, args); 
    } 
} 

class X { 
    public static void main(String... args) { 
    final Calculator calc = new CalculatorImpl(); 
    final Calculator loggingCalc = 
     (Calculator) Proxy.newProxyInstance(X.class.getClassLoader(), 
              new Class[] {Calculator.class}, 
              new LoggingInvocationHandler (calc)); 
    loggingCalc.add(2, 3); // shall print to the screen 
    } 
} 

Można również łatwo zalogować wartości zwracanych i wyjątki generowane przez metod, tylko przez zmianę kodu w InvocationHandler. Można również użyć dowolnej struktury rejestrowania, zamiast wersji System.out.println, jak w przykładzie.

Aby zalogować wartości i wyjątki powrotne, można zrobić coś takiego:

@Override invoke(Object proxy, Method method, Object[] args) throws Throwable { 
    System.out.println("method: " + method + ", args: " + args); 
    try { 
     final Object ret = method.invoke(delegate, args); 
     System.out.println("return: " + ret); 
     return ret; 
    } catch (Throwable t) { 
     System.out.println("thrown: " + t); 
     throw t; 
    } 
    } 
4

Możliwym rozwiązaniem byłoby używać AspectJ. Pomysł polegałby na dołączeniu aspektu do każdej metody, którą chcesz rejestrować, a rejestrowanie to aspekt, a nie metoda. Jednym z przykładów logowania aspektj jest right here in stackoverflow.

Powiązane problemy