Log4j配置 - 不同的日志到不同的文件

时间:2014-04-27 11:06:16

标签: java logging log4j

对于一些人来说,这可能是一个非常简单的问题,但我个人认为Log4j配置非常困难,并且学习进行脑部手术可能不那么具有挑战性。

我正在尝试将多个记录器记录到不同的文件中。 这是我在log4j.properties文件中的内容:

# 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应用程序:

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);中得到例外:

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)

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

文件管理员:日志:

2014-04-27 11:55:30 INFO  admin - hello admin
2014-04-27 11:55:30 INFO  file - hello 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:

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

导致异常的原因是什么,以及如何达到要求的结果?

4 个答案:

答案 0 :(得分:81)

Log4J区分了负责生成日志消息的 loggers appenders ,它们负责在某处发送这些消息(文件,控制台,数据库等)。记录器形成层次结构,根记录器是名为admin的记录器的父级,它是admin.component1的父级等,您可以将appender附加到层次结构中的任何记录器。默认情况下,记录器会将消息发送到直接连接到它的所有appender,或者发送给层次结构中的任何祖先(这就是为什么logger通常被命名为Java类,例如你可以控制com.example.Class1的日志记录和com.example.subpkg.AnotherClass配置com.example记录器。{/ p>

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

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

enter image description here

不应将两个appender附加到根记录器,而应将file appender附加到file记录器,将admin appender附加到admin记录器:< / p>

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

这样,file记录器只会向file.logadmin记录器仅向admin.log发送消息,而向其他发送所有消息记录器将被静默丢弃,因为没有附加到根的appender。

enter image description here


additivity 标志是此规则的例外 - 将记录器的可加性设置为false实际上将箭头从记录器断开连接到其父记录,因此该记录器生成的消息(或从它的一个孩子流入它)不会再向上走到树上,他们只会直接将连接到相关记录器上的追加者

答案 1 :(得分:13)

要回答我自己的问题,这就是我需要的:

log4j.logger.file=DEBUG, fileAppender
log4j.logger.admin=DEBUG, adminAppender

log4j.additivity.file=false
log4j.additivity.admin=false

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

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

答案 2 :(得分:3)

您无需加载属性文件。只需将其放在src文件夹中,该文件夹将自动添加到类路径中。

示例代码:

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

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

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

答案 3 :(得分:-1)

首先:log4j建议使用xml格式文件作为属性。

第二:最好在类加载器中加载属性文件。

第三:记录器中有继承,但您可以使用可加性属性将其删除,请参阅log4j.properties file - multiple loggers in same class