自动检测错误log4j静态初始化的方法
(请注意,它更像是一个Bash问题,而不是Java问题,请参阅下面的注释)
在每个类中配置log4j时,我们执行以下操作:
public class Example { private static final Logger log = Logger.getLogger( Example.class );
问题是我们现在有一个中等大小的代码库(200K LOC),其中包含许多Java类和…相当一些错误配置的log4j记录器。
这是因为人们(包括我,我承认),愚蠢地削减了’n’paste,有时会导致:
public class Another { private static final Logger log = Logger.getLogger( Example.class );
而繁荣,而不是拥有Another.class ,它是旧的Example.class留下,因此错误地出现在日志中(因此引起了不少令人头疼)。
我发现这种错误配置可能会发生但有些奇怪,但现在我们的主要问题不是它可能发生,而是我们必须修复错误的记录器。
我们怎样才能自动检测这些? (修复可以是手动的,但我想找到一种方法来查找log4j配置错误的所有类)。
例如,Bash shell脚本非常受欢迎。
- 对于每个.java文件
- 找到每个“class级XXX”
- 解析下一个’x’行(比如20)
- 有没有Logger.getLogger(…)行?
- 如果是,它是否与“XXX级”匹配?
- 如果没有报道
假阳性不是问题所以如果解析了一些虚假的“类XXX”并不是问题。
注意 :问题实际上是我们现在有200 000行代码,我们想自动检测违规(修复可以是手动)所以问题与以下内容不同:
[有没有更好的方法来获取java中的当前类变量? 1
实际上它可能更像是一个Bash问题而不是Java问题:)
对此最热烈的帮助。
我想如果你正在寻找单线,单线
find -name "*.java" -exec sed -i \ -e 's/private static final Logger \([a-zA-Z_][a-zA-Z0-9_]*).*$/private static final Logger \1 = LoggerFactory.make()/g' \ -e 's/import org\.apache\.log4j\.Logger;/&\nimport path.to.LoggerFactory;/g' \ {} \;
在尝试之前我会备份你的代码。 它可能会在几个地方被打破,但通过一些修正可以得到你想要的东西。 如果您正在使用svn或其他东西,您将不得不调整find以排除.svn
目录,否则您的提交将被搞砸。
要点:甚至不打算尝试捕获类名。 纳入由亚历山大间接链接的解决方案 。 但是用工厂调用替换你的初始Logger声明。 您需要捕获的唯一内容是局部变量的名称。 然后你需要找到你的导入的位置,我假设你可以完全相同,因为你正在导入log4j(或java.util.logging
)。 找到该import
语句并在其下方导入您的工厂。
顺便说一下,关于自动执行此操作的所有警告都是正确的,同样适用于此解决方案。 在尝试这个之后,你需要准备好javac
。 实际上,您应该拥有一些带有怪物代码覆盖率的测试套件,以便在此时自动运行。
在这篇文章中寻找解决方案: 有没有更好的方法来获取java中的当前类变量?
您可以尝试使用AspectJ编织Logger.getLogger
,以确定您的情况中的参数Example.class
是否等于“当前类”名称。
提示 :您可以通过以下方式以编程方式获取“当前类”名称:
String className = new Exception().getStackTrace()[0].getClassName();
未经测试:
find *.java | while read file do lines=$(grep -A 20 "public class .* {" "$file") class=$(echo "$lines" | sed -n '1 s/public class \(.*\) {/\1/p' log=$(echo "$lines" | grep "Logger.getLogger" log=$(echo "$log" | sed -n 's/.*( *\(.*\).class *).*') if [[ "$log" != "$class" ]] then echo "There's a mis-match in file $file, class $class, for logger $log" fi done
FindBugs中可能有一个探测器 – 如果没有,那绝对是一个写…
看看checkstyle。 您可以编写执行此操作的checkstyle自定义规则。 这将是XPath中一个有趣的练习。
但是,如果代码结构非常可预测,我会提出它可以在sed中完成。 如果你想用bash构建计算,那么……
- 使用exec打开文件的文件描述符
- 循环阅读线条
- 当你看到第一个’class’语句时,抓住类名。
- 当你看到Logger结构时,抓住并检查。