包装log4j或创建自定义记录器?

时间:2011-05-16 22:01:22

标签: java logging log4j audit-logging

我有一个应用程序需要记录两种不同类型的消息:应用程序日志消息和审计消息。应用程序日志消息与标准lo4j Logger完全匹配,但审计日志有几个必需参数。

我认为我需要包装log4j以向debug()info()等方法添加其他必需参数,但我讨厌包装log4j的想法。我应该:

  1. 完全包装log4j并提供我自己的Logger类,在classse后面调用log4j记录器?
  2. 扩展log4j Logger类并使用我所需的参数添加“审核日志”方法?
  3. 做一些更优雅的事情,所以我没有包装日志库......

4 个答案:

答案 0 :(得分:4)

log4j error的{​​{1}},warn等方法的“消息”是一个任意对象;它不需要是一个字符串。您可以创建自己的“消息”类来包含不同的参数。记录器可以使用自定义Logger类为审计记录器的附加程序添加不同的数据。

答案 1 :(得分:4)

我认为您可以使用log4j为您的应用程序日志创建日志,如:

private final static Logger log = new Logger(MyClass.class);

为您的审核日志创建一个特定的类别:

private final static Logger log = new Logger("AuditTrail");

您可以在多个类中共享不同的appender,这样您就可以在配置文件中配置输出目标和格式。

希望这有帮助。

答案 2 :(得分:1)

这将有效: 到目前为止,这是我得到的最佳解决方案......

(归功于LOG4J: Modify logged message using custom appender中的 hellojava

创建一个自定义Log4j布局,例如:

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class AuditLayout extends PatternLayout {
    // Audit Summary Map:
    // <Level, Counter>

    private static Map<Level, Integer> auditMap = new HashMap<Level, Integer>();

    public static Map<Level, Integer> getAuditMap() {
        return auditMap;
    }

    public static void setAuditMap(Map<Level, Integer> auditMap) {
        AuditLayout.auditMap = auditMap;
    }

    @Override
    public String format(LoggingEvent event) {

        if (event.getMessage() != null && event.getMessage() instanceof String) {
            // Check the message level and update the audit object accordingly:
            if (!auditMap.containsKey(event.getLevel())) {
                auditMap.put(event.getLevel(), 1); 
            } else {
                int i = auditMap.get(event.getLevel());    
                i++;
                auditMap.put(event.getLevel(), i); 
            }
        }
        return super.format(event);
    }
}

这是一个非常简单的布局,它检查日志级别并在Map中保存摘要; 即DEBUG&gt; 2,INFO&gt; 10 等。

在log4j.properties文件中设置新布局(使用其中一个appender):

# CONSOLE:
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
# BEFORE::: log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
# AFTER:::
log4j.appender.CONSOLE.layout=com.ca.utils.AuditLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{MM/dd/yyyy HH:mm:ss} %-5p %c line: %L - %m%n

现在根据Logger对象在Main类的Layout中使用auditMap:

private static AuditLayout auditLayout = null;
...
if (log.getRootLogger().getAppender("CONSOLE").getLayout() instanceof AuditLayout)
    auditLayout = (AuditLayout) log.getRootLogger().getAppender("CONSOLE").getLayout();
...
System.out.println("auditLayout: " + auditLayout.getAuditMap().toString());

我希望这有帮助!

答案 3 :(得分:0)

可能你可以阅读log4j的api NDC / MDC。希望能帮到你。