自动检测错误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脚本非常受欢迎。

  1. 对于每个.java文件
  2. 找到每个“class级XXX”
  3. 解析下一个’x’行(比如20)
  4. 有没有Logger.getLogger(…)行?
  5. 如果是,它是否与“XXX级”匹配?
  6. 如果没有报道

假阳性不是问题所以如果解析了一些虚假的“类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构建计算,那么……

  1. 使用exec打开文件的文件描述符
  2. 循环阅读线条
  3. 当你看到第一个’class’语句时,抓住类名。
  4. 当你看到Logger结构时,抓住并检查。