Java Log4j - 让多个 appender 写入同一个文件,其中一个总是记录

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4046825/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 10:54:55  来源:igfitidea点击:

Log4j - Have multiple appenders write to the same file with one that always logs

javalogginglog4j

提问by David Buckley

I have a log4j appender defined like:

我有一个 log4j appender,定义如下:

log4j.logger.com.example = DEBUG, filelog

log4j.appender.filelog=org.apache.log4j.DailyRollingFileAppender
log4j.appender.filelog.File=c:/app.log
log4j.appender.filelog.layout=org.apache.log4j.PatternLayout
log4j.appender.filelog.layout.ConversionPattern=%d | %m%n
log4j.appender.filelog.DatePattern=.dd-MM-yyyy

In my class, I get the logger like:

在我的课堂上,我得到了这样的记录器:

Log logger = LogFactory.getLog(getClass());

This works properly. I want to have a logger that always logs certain messages (not errors, but things like how long transactions took). If I write these at DEBUG or INFO, I won't see them if the log level is changed. I think I can accomplish this using another appender that writes to the same file.

这工作正常。我想要一个记录器,它总是记录某些消息(不是错误,而是诸如事务花费了多长时间之类的东西)。如果我在 DEBUG 或 INFO 中编写这些,如果日志级别发生更改,我将看不到它们。我想我可以使用另一个写入同一个文件的 appender 来完成这个。

Is this possible to have two appenders write to the same file? How would I get the logger instance where I want to use the normal debug appender and the transactional appender in the same class? These messages won't all be in the same package, so I can't configure a certain package to always log. Will I have to have these appenders write to different files, or can I retrieve them both in the code and have something like:

这可以让两个 appender 写入同一个文件吗?我将如何获取我想在同一类中使用普通调试附加程序和事务附加程序的记录器实例?这些消息不会都在同一个包中,因此我无法将某个包配置为始终登录。我是否必须让这些 appender 写入不同的文件,或者我可以在代码中检索它们并具有以下内容:

Log alwaysLogger = LogFactory.getLog(ALWAYS);
alwaysLogger.debug("This message will always be written regardless of the level set on the filelog appender");

UpdateI could write to two different log files if necessary, but how would I get the logger instance in my class? I don't want to configure one package/class to always use one appender over the other as the classes will have to log information/error messages and the transactional "always" messages during a normal run. Is there a way to accomplish what I need even if it write to two different log files?

更新如果需要,我可以写入两个不同的日志文件,但是如何在我的类中获取记录器实例?我不想将一个包/类配置为始终使用一个附加程序而不是另一个,因为这些类在正常运行期间必须记录信息/错误消息和事务性“始终”消息。即使写入两个不同的日志文件,有没有办法完成我需要的操作?

回答by darioo

I don't think log4j really supports two appenders writing to the same file because of synchronization issues. Your best bet would be, if possible, to make a switch to slf4jusing Logbackas your backend logging system since Logback is log4j's successor and also supports multiple appenders writing to one file. Check out FileAppenderand it's prudent mode.

由于同步问题,我不认为 log4j 真的支持两个 appender 写入同一个文件。如果可能,您最好的选择是使用Logback作为后端日志记录系统切换到slf4j,因为 Logback 是 log4j 的继承者,并且还支持多个 appender 写入一个文件。查看FileAppender,它是谨慎模式。

Update:from your description, it seems you should also check out markers. You only need one logger instance, and you can get more fine grained control using markers, because with them you basically say "this log statement has a special purpose, and has to be logged using an appropriate appender". You can also check log appender additivity, which is usually used when you use two or more appenders for one log statement.

更新:从您的描述来看,您似乎还应该查看标记。您只需要一个记录器实例,并且可以使用标记获得更细粒度的控制,因为使用它们基本上可以说“此日志语句具有特殊用途,必须使用适当的附加程序进行记录”。您还可以检查 log appender additivity,这通常在您对一个日志语句使用两个或多个 appender 时使用。

回答by Synesso

As far as I'm aware, the instantiation of loggers with a package & class identifier is just a convention. You are free to create multiple logger instances in any class and give them any identifier.

据我所知,使用包和类标识符实例化记录器只是一种约定。您可以在任何类中自由创建多个记录器实例并为它们提供任何标识符。

Log alwaysLogger = LogFactory.getLog("a.b.c.ALWAYS");
Log sometimesLogger = LogFactory.getLog("a.b.c.SOMETIMES");

As for writing to the same file, I have not tried it but it should be possible, at least from a single thread. You may need to write your own appender rather than relying on one of the default ones.

至于写入同一个文件,我还没有尝试过,但应该可以,至少从单个线程开始。您可能需要编写自己的 appender,而不是依赖默认的 appender 之一。

回答by Andrés Oviedo

Yes. You can "workaround" to have 2 appenders writing to the same file.

是的。您可以“解决方法”让 2 个 appender 写入同一个文件。

Checkout this code + example:

查看此代码 + 示例

Any questions welcome.

欢迎任何问题。

回答by Fodder

I got this to work by using AsyncAppenders. I had my main appender which specified a file to log to, and had my other appenders refer to it.

我通过使用AsyncAppenders使其工作。我的主 appender 指定了要登录的文件,并让我的其他 appender 引用它。

e.g.

例如

<appender name="top" class="org.apache.log4j.rolling.RollingFileAppender">
    <param name="file" value="myLog.log" />
</appender>

<appender name="other" class="org.apache.log4j.AsyncAppender">
    <appender-ref ref="top" />
</appender>

<logger name="com.example.MyCLass">
    <appender-ref ref="other" />
</logger>

You can add other filters, or whatever to the other appenders. As far as I can tell with my own app, the logs seem to roll, and the appender filters work as expected.

您可以向其他附加程序添加其他过滤器或任何内容。就我自己的应用程序而言,日志似乎在滚动,并且 appender 过滤器按预期工作。