Java Log4j 配置 - 不同的日志到不同的文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23322602/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Log4j config - different logs to different files
提问by NickJ
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 配置非常困难,而且学习进行脑部手术可能不那么具有挑战性。
I am trying to lave multiple loggers logging into different files. Here is what I have in my log4j.properties file:
我试图让多个记录器登录到不同的文件。这是我的 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
And here is my (very simple) Java app used to test the config:
这是我用于测试配置的(非常简单的)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");
}
I have 2 problems:
我有两个问题:
One problem I always get an exception in the line PropertyConfigurator.configure(resource);
:
一个问题我总是在行中遇到异常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 actualresult:
第二个问题是两条消息都写入了两个日志。这是实际结果:
File admin:log:
文件管理员:日志:
2014-04-27 11:55:30 INFO admin - hello admin
2014-04-27 11:55:30 INFO file - hello file
File file.log:
文件file.log:
2014-04-27 11:55:30 INFO admin - hello admin
2014-04-27 11:55:30 INFO file - hello file
Here is the requiredresult:
这是所需的结果:
File admin:log:
文件管理员:日志:
2014-04-27 11:55:30 INFO admin - hello admin
File file.log:
文件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?
导致异常的原因是什么,我如何才能达到所需的结果?
回答by Braj
You don't need to load the properties file. Just place it inside the src
folder that will automatically added in class path.
您不需要加载属性文件。只需将它放在src
将自动添加到类路径中的文件夹中。
Sample code:
示例代码:
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");
}
回答by spopoff
First: log4j recommands to use xml format file for properties.
第一:log4j 建议使用 xml 格式的属性文件。
Second: its better to load the properties file in the classloader.
第二:最好在类加载器中加载属性文件。
Third: there is inheritance in logger, but you can cut it with additivity property see log4j.properties file - multiple loggers in same class
第三:记录器中有继承,但您可以使用可加性属性对其进行切割,请参见log4j.properties 文件 - 同一类中的多个记录器
回答by NickJ
To answer my own question, this is what I needed:
要回答我自己的问题,这就是我需要的:
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
回答by Ian Roberts
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).
Log4J的可区分记录器,其负责生成日志消息,并且追加程序,其负责某处发送这些消息(文件时,控制台,数据库等)。记录器形成层次结构,根记录器是名为 的记录器的父级admin
,它是 等的父级admin.component1
,您可以将附加程序附加到层次结构中的任何记录器。默认情况下,一个记录器将邮件发送到直接连接到它,或在层次结构及其祖先(这就是为什么记录仪通常被命名为喜欢的Java类,例如,你可以控制记录的所有追加程序com.example.Class1
,并com.example.subpkg.AnotherClass
通过配置com.example
记录器) .
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.
记录器和附加器形成单独的命名空间,这是您混淆的根源 - 记录器命名admin
和附加器命名admin
是两个独立的实体。
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 loggersand 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 bothof the configured appenders.
您在问题中给出的配置定义了一个记录器(根记录器),它将它生成的所有消息发送到两个单独的appender,一个用于两个文件中的每一个。然后您的代码请求两个不同的记录器并为每个记录器生成一条日志消息。这两个记录器都从根记录器继承了 appender 配置,因此它们都将消息发送到两个已配置的 appender。
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:
不是将两个 appender 附加到根记录器,您应该将file
appender 附加到file
记录器,将admin
appender 附加到admin
记录器:
log4j.rootLogger=INFO
log4j.logger.file=INFO, file
log4j.logger.admin=INFO, admin
This way the file
logger will send messages only to file.log
, the admin
logger only to admin.log
, and all messages from otherloggers will be silently discarded, as there are no appenders attached to the root.
这样file
记录器将只发送消息到file.log
,admin
记录器只发送到admin.log
,并且来自其他记录器的所有消息都将被静默丢弃,因为没有附加到根的附加程序。
The additivityflag 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 directlyto the logger in question.
可加性标志是此规则的一个例外 - 将记录器的可加性设置为 false 基本上会断开从记录器到其父级的箭头,因此该记录器生成的消息(或从其子代之一流入)将不会再进一步在树上,它们只会转到直接附加到相关记录器的附加程序。