How can i log every method called in a class automatically with log4j

后端 未结 3 1515
粉色の甜心
粉色の甜心 2021-02-02 14:17

I have a class with database calls, and I generally want to log every method called (with arguments) in this class with log4j:

logger.debug(\"foo(id=\"+id+\") in         


        
3条回答
  •  一整个雨季
    2021-02-02 14:28

    If you have interfaces declaring the methods you want to log calls to, you can use the standard Proxy API to achieve what you want.

    The Proxy API would allow you to wrap your actual implementation in a new, proxy class, that would log the call, and the forward the call to implementation. You just have to implement one InvocationHandler that does the logging and the forwarding.

    For example,

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

    You can also easily log the return values and exceptions thrown by the methods, just by changing the code in the InvocationHandler. Also, you could use any logging framework you like instead of System.out.println as in the example.

    To log return values and exceptions, you could do something like:

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

提交回复
热议问题