我是Log4J v.1.2.15的新用户,因为我的一位朋友使我相信其优于控制台或其他形式的日志记录。但是,当我做一些测试时,我遇到了一个让我思考的测试用例。这就是我所做的:
ConsoleAppender
和RollingFileAppender
。Logger mainLogger = Logger.getLogger(Main.class);
我在库中有这个通用的,手工制作的java utils集合,叫做
MyUtils.jar
,添加到我的主应用程序的类路径中。在主应用程序中,我从MyUtils.jar
调用了静态方法。此方法有一个try-catch {}块,并在那里处理异常,使用System.err打印堆栈跟踪。
现在,使用我的IDE和ConsoleAppender
,我能够发现问题,但是,事件未记录在我的文件日志中。这里有两个问题需要解答:
a。我目前正在使用mainLogger
来记录我应用的所有类中的事件。这是一个好习惯吗?或者我应该为X类使用X记录器实例?
b。如果能够记录我的导入中已捕获的错误,我该怎么办?
这可能听起来微不足道,但我使用了Object foo = MyLibrary.composeObjectFoo()
,
在方法内部看起来类似于这个例子:
public static Object composeObjectFoo() {
try {
.....statements.....
.
.
// something stupid here
int a = 100/0; //an AritmethicException will be thrown
} catch Exception(e) {
e.printStackTrace();
}
}
感谢您的回答,请原谅这个问题......
答案 0 :(得分:3)
我建议记录一些事项:
System.out.println()
,System.err.println()
或e.printStackTrace()
。而是使用记录器。您可以将记录器配置为打印到stdout或stderr,更不用说过滤掉不重要的信息了。更加灵活。Logger.getLogger(Main.class)
)。通过执行此操作,您可以使用所有这些唯一的记录器名称来微调日志过滤。例如,如果需要,您可以将A类设置为debug
,将B类设置为info
。slf4j
这样的记录器抽象层(我真的很喜欢这个)或commons-logging
。这样您就可以更改记录器实现,而无需查看所有代码并更改登录的每个位置。关于例外情况:
我还建议您阅读一些关于异常处理最佳实践的内容。每个人都会争论什么是“最好的”,但是所有人都应该同意你应该做的不仅仅是让所有事情都泄漏到main()
。我喜欢this article所说的内容。
答案 1 :(得分:1)
您可以在主类中更改System.out和System.err以打印采用打印内容的流并将其传递给记录器。它听起来有点复杂,但它已经在开源项目中完成(例如JBoss有一个实现),所以你可以从那里得到它。
答案 2 :(得分:0)
我做了一个合乎逻辑的事情..我已经从我的Utils类中删除了try-> catch {}块。现在生成的异常被主应用程序捕获并记录。真棒!但是......有没有保证在使用第三方创建的libs / utils时情况不会重演?
答案 3 :(得分:0)
您无法记录导入库中捕获的异常。您无法将代码添加到导入的库中。一旦它被抓住,你就完成了。您可以期待的最好的是导入的库重新抛出异常并为您提供记录内容的机会。
我想知道导入的库的质量,它不会记录并写入控制台。这不是一个好的设计概念。
我不喜欢主类做日志记录的想法。你的直觉很好,但你的实施却不是。记录是一个跨领域的问题,应该使用面向方面的编程来完成。
答案 4 :(得分:0)
一个。我目前正在使用mainLogger 记录我所有类别的事件 应用程序。这是一个好习惯吗?要么 我应该为X使用X记录器实例吗? 类?
创建和使用多个Logger通常是个更好的主意。这使您(或稍后有人)通过日志记录配置更好地控制日志记录级别等。但我不一定建议在每个类中创建一个(静态)Logger实例。
湾我能做些什么来记录 我的导入中已经出现错误?
除了对导入的代码库进行大修以改进其内部错误报告和日志记录之外,您无法做到这一点。
另一方面,如果您要创建可能在其他地方重用的库代码,则应注意获取错误报告和正确记录。特别是,清除不恰当的使用System.err
,printStackTrace()
等。使用日志记录抽象层也是一个好主意,这样就不会给集成库的人带来麻烦。
答案 5 :(得分:0)
好的,在更多文档之后,我遇到了这个解决方案,记录所有内容,无论源代码是否在您的其他地方的代码中:
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable exc) {
//do something about it
}
});
这样,我能够捕获并报告导入库中发生的异常状态,但未处理或重新调整。就像
这样愚蠢的事情 public double computeValue(int val){
double a = 15/val;
return a;
}
和val为0,生成ArithmeticException,而不是抛出而没有捕获。