java 如何使用 log4j 自动记录在类中调用的每个方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13356326/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can i log every method called in a class automatically with log4j
提问by Peeer
I have a class with database calls, and I generally want to log every method called (with arguments) in this class with log4j:
我有一个带有数据库调用的类,我通常想用 log4j 记录这个类中调用的每个方法(带参数):
logger.debug("foo(id="+id+") initiated");
Is it possible to do this automatically? Maybe by using some sort of annotation in start of each method instead of writing every single logger.debug?
是否可以自动执行此操作?也许通过在每个方法的开头使用某种注释而不是编写每个 logger.debug?
Today I have to update my logging.debug every time I change arguments or method name.
今天,每次更改参数或方法名称时,我都必须更新我的 logging.debug。
采纳答案by yegor256
Try @Loggable
annotation and an AspectJ aspect from jcabi-aspects(I'm a developer):
尝试@Loggable
注释和来自jcabi-aspects的 AspectJ方面(我是一名开发人员):
@Loggable(Loggable.INFO)
public String load(URL url) {
return url.openConnection().getContent();
}
All method calls are logged through SLF4J.
所有方法调用都通过 SLF4J 记录。
This blog post explains it step by step: Java Method Logging with AOP and Annotations
这篇博文逐步解释了它:Java Method Logging with AOP and Annotations
回答by Bruno Reis
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.
如果您有接口声明要记录调用的方法,则可以使用标准代理 API 来实现您想要的。
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.
代理 API 将允许您将实际实现包装在一个新的代理类中,该类将记录调用并将调用转发到实现。您只需要实现一个InvocationHandler
进行日志记录和转发的功能。
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.
您还可以轻松地记录方法抛出的返回值和异常,只需更改InvocationHandler
. 此外,您可以使用任何您喜欢的日志记录框架,而不是System.out.println
像示例中那样。
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;
}
}
回答by Ahe
One possible solution would be to use aspectj. Idea would be to attach aspect to every method you wish to log, and perform logging is aspect instead of a method. One example of aspectj logging is right here in stackoverflow.
一种可能的解决方案是使用aspectj。想法是将方面附加到您希望记录的每个方法上,并且执行日志记录是方面而不是方法。在 stackoverflow 中,aspectj 日志记录的一个例子就在这里。