对于一些人来说,这可能是一个非常简单的问题,但我个人认为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
导致异常的原因是什么,以及如何达到要求的结果?
答案 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的两个。
不应将两个appender附加到根记录器,而应将file
appender附加到file
记录器,将admin
appender附加到admin
记录器:< / p>
log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin
这样,file
记录器只会向file.log
,admin
记录器仅向admin.log
发送消息,而向其他发送所有消息记录器将被静默丢弃,因为没有附加到根的appender。
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