Log4j 配置 - 不同的日志到不同的文件 [英] Log4j config - different logs to different files

查看:31
本文介绍了Log4j 配置 - 不同的日志到不同的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于某些人来说,这可能是一个非常简单的问题,但我个人认为 Log4j 配置非常困难,而且学习进行脑部手术可能没有那么困难.

This might be a very easy question for some, but personally I find Log4j config to be nightmarishly difficult and that learning to perform brain surgery might be less challenging.

我试图让多个记录器登录不同的文件.这是我的 log4j.properties 文件中的内容:

I am trying to lave multiple loggers logging into different files. Here is what I have in my log4j.properties file:

# Root logger option
log4j.rootLogger=INFO, file, admin

# Direct log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=/home/nick/logging/file.log
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=1
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

log4j.appender.admin=org.apache.log4j.RollingFileAppender
log4j.appender.admin.File=/home/nick/logging/admin.log
log4j.appender.admin.MaxFileSize=1MB
log4j.appender.admin.MaxBackupIndex=1
log4j.appender.admin.layout=org.apache.log4j.PatternLayout
log4j.appender.admin.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1} - %m%n

这是我用来测试配置的(非常简单的)Java 应用程序:

And here is my (very simple) Java app used to test the config:

public static void main(String[] args) throws Exception {

    Properties resource = new Properties();
    InputStream in = new FileInputStream("/home/nick/logging/log4j.properties");
    resource.load(in);
    PropertyConfigurator.configure(resource);

    Logger admin = Logger.getLogger("admin");
    Logger file = Logger.getLogger("file");

    admin.info("hello admin");
    file.info("hello file");
}

我有两个问题:

一个问题,我总是在 PropertyConfigurator.configure(resource);:

One problem I always get an exception in the line PropertyConfigurator.configure(resource);:

java.io.FileNotFoundException: /home/nick/logging (Is a directory)
 at java.io.FileOutputStream.open(Native Method)
 at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
 at java.io.FileOutputStream.<init>(FileOutputStream.java:136)
 at org.apache.log4j.FileAppender.setFile(FileAppender.java:289)
 at org.apache.log4j.RollingFileAppender.setFile(RollingFileAppender.java:167)
 at org.apache.log4j.FileAppender.activateOptions(FileAppender.java:163)
 at org.apache.log4j.config.PropertySetter.activate(PropertySetter.java:256)

第二个问题是两条消息都写入了两个日志.这是实际结果:

The 2nd problem is that both messages are written to both logs. Here is the actual result:

文件管理员:日志:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

文件file.log:

File file.log:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello file

这是必需的结果:

文件管理员:日志:

2014-04-27 11:55:30 INFO  admin - hello admin

文件file.log:

File file.log:

2014-04-27 11:55:30 INFO  file - hello file

导致异常的原因是什么,我怎样才能达到要求的结果?

What is causing the exception, and how can I achieve the required result?

推荐答案

Log4J 区分了负责生成日志消息的 loggers 和负责生成日志消息的 appenders负责将这些消息发送到某个地方(文件、控制台、数据库等).Logger 形成一个层次结构,根 logger 是名为 admin 的 logger 的父级,它是 admin.component1 等的父级,你可以将 appender 附加到任何层次结构中的记录器.默认情况下,记录器将向直接附加到它的所有附加程序或层次结构中的任何祖先发送消息(这就是为什么记录器通常命名为 Java 类的原因,例如,您可以控制 com.example 的日志记录.Class1com.example.subpkg.AnotherClass 通过配置 com.example 记录器).

Log4J makes a distinction between loggers, which are responsible for generating log messages, and appenders, which are responsible for sending those messages somewhere (a file, the console, a database, etc.). Loggers form a hierarchy, the root logger is the parent of the logger named admin, which is the parent of admin.component1, etc., and you can attach appenders to any logger in the hierarchy. By default a logger will send messages to all appenders that are attached directly to it, or to any of its ancestors in the hierarchy (this is why loggers are conventionally named like Java classes, e.g. you can control logging for com.example.Class1 and com.example.subpkg.AnotherClass by configuring the com.example logger).

记录器和附加器形成独立的命名空间,这是您混淆的根源 - 名为 admin 的记录器和名为 admin 的附加器是两个独立的实体.

Loggers and appenders form separate namespaces and this is the source of your confusion - the logger named admin and the appender named admin are two separate entities.

您在问题中给出的配置定义了一个记录器(根记录器),它将它生成的所有消息发送到两个单独的 appender,一个用于两个文件中的每一个.然后您的代码请求两个不同的记录器,并为每个记录器生成一条日志消息.这两个记录器都从根记录器继承了 appender 配置,因此它们都将消息发送到两个已配置的 appender.

The configuration you have given in the question defines one logger (the root logger) which sends all the messages it generates to two separate appenders, one for each of the two files. Your code then requests two different loggers and generates one log message with each logger. Both these loggers inherit the appender configuration from the root logger, so they both send their messages to both of the configured appenders.

不是将两个 appender 附加到根记录器,您应该将 file 附加器附加到 file 记录器,将 admin 附加器附加到admin 记录器:

Instead of attaching the two appenders to the root logger, you should attach the file appender to the file logger and the admin appender to the admin logger:

log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin

这样 file 记录器只会将消息发送到 file.logadmin 记录器只会发送到 admin.log,并且来自其他记录器的所有消息都将被静默丢弃,因为没有附加到根的附加程序.

This way the file logger will send messages only to file.log, the admin logger only to admin.log, and all messages from other loggers will be silently discarded, as there are no appenders attached to the root.

additivity 标志是此规则的例外 - 将记录器的可加性设置为 false 基本上断开了从记录器到其父级的箭头,因此该记录器生成的消息(或从它的一个子节点)不会在树上再往上走,它们只会去直接附加到相关记录器的附加程序.

The additivity flag is the exception to this rule - setting a logger's additivity to false essentially disconnects the arrow from a logger up to its parent, so messages generated by that logger (or flowing into it from one of its children) will not go any further up the tree, they will only go to appenders attached directly to the logger in question.

这篇关于Log4j 配置 - 不同的日志到不同的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆