java 为什么 log4j 没有登录到我使用 log4j.xml 文件配置的文件?

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

why does log4j not log to the files I configured it to with a log4j.xml file?

javatomcatlog4j

提问by user26270

I've run into this in various environments and have never found a consistent explanation. I've heard comments about the Tomcat container being 'messy', with different logging implementations possibly in there, and then my app or the classloader doesn't know which configuration to use.

我在各种环境中都遇到过这种情况,但从未找到一致的解释。我听说过关于 Tomcat 容器“乱七八糟”的评论,其中可能有不同的日志记录实现,然后我的应用程序或类加载器不知道要使用哪种配置。

This is one of those maddening scenarios when the logging worked once, and then doesn't log an hour later, with no changes to the log4j.xml file. I've got my log4j.xml file in the root of my /src directory, so it gets deployed to the root of the /WEB-INF/classes directory. I'm using Java 6, Tomcat 6, and it's a GWT 2.3 app, running from inside Eclipse Helios on a Windows 7 box.

这是一种令人抓狂的场景,即记录工作一次,然后一小时后没有记录,log4j.xml 文件没有任何更改。我的 log4j.xml 文件位于 /src 目录的根目录中,因此它被部署到 /WEB-INF/classes 目录的根目录中。我使用的是 Java 6、Tomcat 6,它是一个 GWT 2.3 应用程序,从 Windows 7 机器上的 Eclipse Helios 内部运行。

For what it's worth, here's the log4j.xml

对于它的价值,这里是 log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE}
      %5p %c{1}:%L - %m%n"/>
        </layout>
    </appender>
    <appender name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${catalina.home}/logs/log4j.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <param name="Append" value="true"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d
                %-5p  [%c{1}] %m %n" />
        </layout>
    </appender>
    <root>
        <priority value="debug"></priority>
        <appender-ref ref="fileAppender"/>
    </root>
</log4j:configuration>

here's how I get the logger in my class that's doing the logging

这是我如何在我的班级中获得记录器的记录器

protected static Logger m_logger = Logger.getLogger(RemoteLoggingServiceImpl.class);

and then to actually log I just do

然后实际登录我就做

m_logger.debug("my log message");

Using the above code, it doesn't write to the logj4.log file.

使用上面的代码,它不会写入 logj4.log 文件。

Then I tried the following, which got it logging to the log4j.log file, but not to the otherFile.log file as I expected. Here's the updated log4j.xml file :

然后我尝试了以下操作,将它记录到 log4j.log 文件,但没有像我预期的那样记录到 otherFile.log 文件。这是更新的 log4j.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
    <appender name="stdout" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ABSOLUTE}
      %5p %c{1}:%L - %m%n"/>
        </layout>
    </appender>
    <appender name="fileAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${catalina.home}/logs/log4j.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <param name="Append" value="true"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d
                %-5p  [%c{1}] %m %n" />
        </layout>
    </appender>
    <appender name="otherFileAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="${catalina.home}/logs/otherFile.log"/>
        <param name="DatePattern" value="'.'yyyy-MM-dd"/>
        <param name="Append" value="true"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d
                %-5p  [%c{1}] %m %n" />
        </layout>
    </appender>
    <root>
        <priority value="debug"></priority>
        <appender-ref ref="fileAppender"/>
    </root>
    <logger name="com.mypackage.myLoggingClass">
        <level value="debug"/>
        <appender-ref ref="otherfileAppender"/>
    </logger>
</log4j:configuration>

and I create this logger with this instead :

我用这个创建了这个记录器:

protected static Logger m_logger = Logger.getLogger("com.mypackage.myLoggingClass");

Can anyone explain why it doesn't log at all in the first scenario, and/or why it logs to log4j.log but not otherFile.log in the 2nd scenario?

谁能解释为什么它在第一个场景中根本不登录,和/或为什么它在第二个场景中登录到 log4j.log 而不是 otherFile.log?

回答by brandonsimpkins

First off, you didn't list what version of Log4j you are using, so I'm assuming you're using a relatively recent version of Log4j.

首先,您没有列出您使用的 Log4j 版本,所以我假设您使用的是相对较新的 Log4j 版本。

In the first block of example code you provided:

在您提供的第一个示例代码块中:

    <root>
        <priority value="debug"></priority>
        <appender-ref ref="fileAppender"/>
    </root>

You have not modified the logging level of the root appender. Per the log4j 2.x documentation

您尚未修改根 appender 的日志记录级别。根据 log4j 2.x 文档

    If no configuration files are present logback will default to the 
    DefaultConfiguration which will set up a minimal logging environment
    consisting of a ConsoleAppender attached to the root logger. The output
    will be formatted using a PatternLayout set to the pattern 
    "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n".

    Note that by default, the root logger is assigned to Level.ERROR.

In order have the logger output to the file in the first example you need to change your root logger to:

为了将记录器输出到第一个示例中的文件,您需要将根记录器更改为:

    <root level="debug">
        <appender-ref ref="fileAppender"/>
    </root>    

A good indicator that the debug logging wasn't working is that you wouldn't have seen any output on the console either since the default logging level was set to "error". I always like to have a console appender on my loggers, so that I can see that my application is actually logging.

调试日志不工作的一个很好的指标是你不会在控制台上看到任何输出,因为默认日志级别设置为“错误”。我总是喜欢在我的记录器上有一个控制台 appender,这样我就可以看到我的应用程序实际上正在记录。

    <appender-ref ref="Console"/>

In the second example, the root logger does not log to the file for precisely the same reason as in the first example. However you managed to set the "com.mypackage.myLoggingClass" logger up correctly, which is why your application has debug output when you use the "com.mypackage.myLoggingClass" class based logger.

在第二个示例中,根记录器没有记录到文件的原因与第一个示例完全相同。但是,您设法正确设置了“com.mypackage.myLoggingClass”记录器,这就是当您使用基于“com.mypackage.myLoggingClass”类的记录器时您的应用程序具有调试输出的原因。

回答by Ayan Paul

Your JRE uses a file named logging.propertiesto set the handlers and log levels and a few other settings to be shared globally across all Java commands.
Many a times its seen that default is handlers= java.util.logging.ConsoleHandler, you can try appending java.util.logging.FileHandlerlike below.

您的 JRE 使用一个名为的文件logging.properties来设置处理程序和日志级别以及一些其他设置,以便在所有 Java 命令之间全局共享。
很多时候它看到默认是handlers= java.util.logging.ConsoleHandler,你可以尝试java.util.logging.FileHandler像下面这样附加。

handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler

Also try settng the file formatter to SimpleFormatter instead of XML formatter

也尝试将文件格式化程序设置为 SimpleFormatter 而不是 XML 格式化程序

java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter

回答by gerrytan

As far as I can see all your original assumptions are correct and the log should be printed, so here's a few things I'd check in this case:

据我所知,您的所有原始假设都是正确的,并且应该打印日志,因此在这种情况下,我会检查以下几点:

  • Check your classpath, did you import other logging library jars causing conflicts (slf4j, common-logging etc)?
  • Check your imports, was it really org.apache.log4j.*, not other logging libraries
  • Check gwt logging guide, does it conflicts with log4j?
  • Check the file system lock on log4j.log, is there any other process locking it causing writes to fail?
  • Check your war/ear file, was log4j.xml really placed on WEB-INF/classes?
  • Check ${catalina.home} does resolve to the path you intended
  • 检查您的类路径,您是否导入了其他导致冲突的日志库 jar(slf4j、common-logging 等)?
  • 检查您的导入,它真的是 org.apache.log4j.*,而不是其他日志库
  • 检查gwt logging guide,它是否与 log4j 冲突?
  • 检查 log4j.log 上的文件系统锁定,是否有其他进程锁定它导致写入失败?
  • 检查你的war/ear 文件,log4j.xml 真的放在WEB-INF/classes 上吗?
  • 检查 ${catalina.home} 确实解析到您想要的路径