Log4j config – 不同的日志到不同的文件
对于一些人来说,这可能是一个非常简单的问题,但我个人认为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);
遇到exceptionPropertyConfigurator.configure(resource);
:
java.io.FileNotFoundException: /home/nick/logging (Is a directory) at java.io.FileOutputStream.open(Native Method) at java.io.FileOutputStream.(FileOutputStream.java:212) at java.io.FileOutputStream.(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
导致exception的原因是什么,我如何才能达到要求的结果?
Log4J区分了负责生成日志消息的记录器和负责在某处(文件,控制台,数据库等)发送这些消息的appender 。 记录器形成层次结构,根记录器是名为admin
的记录器的父级,它是admin.component1
的父级等,您可以将appender附加到层次结构中的任何记录器。 默认情况下,记录器会将消息发送到直接连接到它的所有appender,或者发送给层次结构中的任何祖先(这就是为什么logger通常被命名为Java类,例如你可以控制com.example.Class1
和com.example.subpkg.AnotherClass
通过配置com.example
记录器)。
记录器和追加器形成单独的命名空间,这是您混淆的原因 – 名为admin
的记录器和名为admin
的appender是两个独立的实体。
您在问题中给出的配置定义了一个记录器(根记录器),它将它生成的所有消息发送到两个独立的appender ,每个appender对应两个文件。 然后,您的代码会请求两个不同的记录器,并为每个记录器生成一条日志消息。 这两个记录器都从根记录器inheritanceappender配置,因此它们都将消息发送到两个配置的appender。
您应该将file
appender附加到file
记录器,将admin
appender附加到admin
记录器,而不是将两个appender附加到根记录器:
log4j.rootLogger=INFO log4j.logger.file=INFO, file log4j.logger.admin=INFO, admin
这样, file
记录器将仅向admin.log
发送消息, admin
记录器仅发送到admin.log
,并且将以静默方式丢弃来自其他记录器的所有消息,因为没有附加到根的appender。
additivity标志是此规则的例外 – 将记录器的可加性设置为false实际上将箭头从记录器断开连接到其父记录,因此该记录器生成的消息(或从其子节点流入它的消息)将不再进一步在树上,他们只会直接连接到有问题的记录器。
要回答我自己的问题,这就是我需要的:
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
您不需要加载属性文件。 只需将其放在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"); }
第一:log4j建议使用xml格式文件作为属性。
第二:最好在类加载器中加载属性文件。
第三:在logger中有inheritance,但你可以用additive属性来删除它看到log4j.properties文件 – 同一个类中的多个记录器