标准化企业产品中的日志记录

MonkWhoSoldHisCode

我使用的软件的日志记录高度不一致。所有日志记录都在一个文件中完成,并且该文件包含来自不同模块和客户端交互的日志记录详细信息。日志文件非常混乱,我至少要做的是在该行的开头添加一些模块信息。例如,如下所示,我希望在日志的开头打印模块

#|2014-07-02T13:01:51.030+0530|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=104;_ThreadName=Thread-3;|3131149 [pool-23-thread-18] [rid=1112 session=f5fc97b0ac1802b000b94819c9518996 user=TTUser13] INFO **[MODULE1]**  com.xxxxx.Manager  - Client manager - getMo(Test) request received |#]

[#|2014-07-02T13:01:51.033+0530|INFO|glassfish3.1.1|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=104;_ThreadName=Thread-3;|3131153 [pool-23-thread-18] [rid=1112 session=f5fc97b0ac1802b000b94819c9518996 user=TTUser13] INFO **[MODULE2]** com.xxxxx.server.CliRmiService  - getMo(f5fc97b0ac1802b000b94819c9518996) - 3ms - com.xxxxx.ManagerObject@10f7afd

我关于跨模块进行个人日志记录的建议遭到了许多怀疑的点头(不允许)。因此,我最想做的就是能够在每行的开头添加MODULE信息。我在软件中使用SPRING,JAVA和log4j(slf4j包装器)。有没有更简单的方法可以做到这一点?我不想转到每个记录器语句并添加该标头。那将非常不便。另外,还有其他方法可以解决此问题吗?

克里加克斯

解决该问题的最佳方法是重构代码并引入所需的日志记录。仅仅因为人们希望避免接触遗留代码而产生的怀疑点头是一种嗅觉,而不是争论。

现在,回答您的问题:即使不是为了弥补不良的设计或不良的日志记录习惯而发明AOP的,也可以将AspectJ用于您的目的。这里不适合使用像Spring AOP这样的“ AOP lite”框架,因为Spring AOP仅支持方法执行拦截,不支持方法调用拦截,这是您在这里需要的。

这是一个简单的AspectJ示例。请注意,每当我说“模块”时,我指的是软件包名称的最后一部分(在最后一个“。”之后),例如module1,如果软件包名称为,则为模块名称de.scrum_master.module1

不同模块中的两个样本类:

package de.scrum_master.module1;

import java.util.logging.Logger;

public class Person {
    private String firstName;
    private String lastName;

    public Person(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; }
    @Override public String toString() { return "Person[" + firstName + " " + lastName + "]"; }
    public void doSomething() { Logger.getLogger("GLOBAL").info("Doing something with " + this); }
    public void doSomethingElse() { Logger.getLogger("GLOBAL").info("Doing something else with " + this); }
}
package de.scrum_master.module2;

import java.util.logging.Logger;

public class Place {
    private String country;
    private String city;

    public Place(String country, String city) { this.country = country; this.city = city; }
    @Override public String toString() { return "Place[" + city + ", " + country + "]"; }
    public void doSomething() { Logger.getLogger("GLOBAL").info("Doing something with " + this); }
    public void doSomethingElse() { Logger.getLogger("GLOBAL").info("Doing something else with " + this); }
}

使用模块的驱动程序应用程序:

package de.scrum_master.app;

import java.util.logging.Logger;

import de.scrum_master.module1.Person;
import de.scrum_master.module2.Place;

public class Application {
    private static final Logger LOG = Logger.getLogger("GLOBAL");

    public static void main(String[] args) {
        doPersonStuff();
        doPlaceStuff();
    }

    private static void doPersonStuff() {
        LOG.info("Start doing person stuff...");
        Person person = new Person("Albert", "Einstein");
        person.doSomething();
        person.doSomethingElse();
        person = new Person("Werner", "Heisenberg");
        person.doSomething();
        person.doSomethingElse();
        LOG.info("Finished doing person stuff");
    }

    private static void doPlaceStuff() {
        LOG.info("Start doing place stuff...");
        Place place = new Place("Indonesia", "Jakarta");
        place.doSomething();
        place.doSomethingElse();
        place = new Place("Germany", "Berlin");
        place.doSomething();
        place.doSomethingElse();
        LOG.info("Finished doing place stuff");
    }
}

方面:

Aspect在[MODULE1]每个日志消息之前都添加了大写的模块名称前缀使方面根据类或程序包名称登录到不同的日志文件中将非常简单。这只是一个示范。

package de.scrum_master.aspect;

import java.util.logging.Logger;

public aspect LogModulePrepender {
    void around(String message) :
        call(public void Logger.*(String)) && args(message)
    {
        String packageName = thisJoinPoint.getSourceLocation().getWithinType().getPackage().getName();
        String moduleName = packageName.replaceFirst(".*[.]", "").toUpperCase();
        proceed("[" + moduleName + "] " + message);
    }
}

日志输出:

请注意,为简单起见,在一起整理此小样本时,我使用Java日志记录而不是Log4j。它应该很容易适应。

Jul 25, 2014 11:11:48 AM de.scrum_master.app.Application info_aroundBody0
Information: [APP] Start doing person stuff...
Jul 25, 2014 11:11:48 AM de.scrum_master.module1.Person info_aroundBody0
Information: [MODULE1] Doing something with Person[Albert Einstein]
Jul 25, 2014 11:11:48 AM de.scrum_master.module1.Person info_aroundBody2
Information: [MODULE1] Doing something else with Person[Albert Einstein]
Jul 25, 2014 11:11:48 AM de.scrum_master.module1.Person info_aroundBody0
Information: [MODULE1] Doing something with Person[Werner Heisenberg]
Jul 25, 2014 11:11:48 AM de.scrum_master.module1.Person info_aroundBody2
Information: [MODULE1] Doing something else with Person[Werner Heisenberg]
Jul 25, 2014 11:11:48 AM de.scrum_master.app.Application info_aroundBody2
Information: [APP] Finished doing person stuff
Jul 25, 2014 11:11:48 AM de.scrum_master.app.Application info_aroundBody4
Information: [APP] Start doing place stuff...
Jul 25, 2014 11:11:48 AM de.scrum_master.module2.Place info_aroundBody0
Information: [MODULE2] Doing something with Place[Jakarta, Indonesia]
Jul 25, 2014 11:11:48 AM de.scrum_master.module2.Place info_aroundBody2
Information: [MODULE2] Doing something else with Place[Jakarta, Indonesia]
Jul 25, 2014 11:11:48 AM de.scrum_master.module2.Place info_aroundBody0
Information: [MODULE2] Doing something with Place[Berlin, Germany]
Jul 25, 2014 11:11:48 AM de.scrum_master.module2.Place info_aroundBody2
Information: [MODULE2] Doing something else with Place[Berlin, Germany]
Jul 25, 2014 11:11:48 AM de.scrum_master.app.Application info_aroundBody6
Information: [APP] Finished doing place stuff

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章