4

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

我想我需要包装 log4j 以将额外的必需参数添加到debug(),info()等方法中,但我讨厌包装 log4j 的想法。我是不是该:

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

4 回答 4

4

errorlog4j 的,warn等方法的“消息”Logger是任意对象;它不需要是一个字符串。您可以创建自己的“消息”类来包含不同的参数。Layout记录器可以通过为审计记录器的附加器使用自定义类来以不同的方式附加数据。

于 2011-05-16T22:14:34.243 回答
4

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

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

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

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

拥有一个可以跨多个类共享的不同附加程序将允许您在配置文件中根据需要配置输出目标和格式。

希望这可以帮助。

于 2011-05-16T22:54:13.817 回答
1

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

(归功于LOG4J中的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 中保存摘要;即调试> 2,信息> 10等。

在您的 log4j.properties 文件中设置新的布局(使用您的附加程序之一):

# 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());

我希望这有帮助!

于 2017-04-27T12:30:49.883 回答
0

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

于 2011-11-07T03:13:35.343 回答