【问题标题】:Log4j: How to configure simplest possible file logging?Log4j:如何配置最简单的文件日志记录?
【发布时间】:2011-06-15 13:56:25
【问题描述】:

我的故事:

我想做一个像最简单的 log4j 记录器一样简单的东西,它将行记录到文件中。我找到了几个具有某些功能的示例,但不是真正有效的基本通用示例,也没有解释每一行如何工作的示例。

问题:

有人可以提供吗?

先决条件:

  • 我已经知道将文件放在哪里,并且我已经配置了 log4j 并且可以用于控制台日志记录。
  • 现在我想登录到一个文件,并在程序运行后从文件系统中找到该文件。
  • 需要添加到现有log4j.properties 文件的行是所需的输出。

【问题讨论】:

  • 这是一个关于同一主题的老问题:stackoverflow.com/questions/4474646/…
  • 这是我第一次为我的项目配置文件附加程序。应该授予什么权限,以便日志记录真正进入文件。我几乎不记得过去的事情,至少文件的文件权限应该是固定的,可能还有其他一些与程序相关的权限。我在 Linux 上做这个。

标签: java logging log4j


【解决方案1】:

我有一个通用的 log4j.xml 文件给你:

<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration debug="false">

    <appender name="default.console" class="org.apache.log4j.ConsoleAppender">
        <param name="target" value="System.out" />
        <param name="threshold" value="debug" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
        </layout>
    </appender>

    <appender name="default.file" class="org.apache.log4j.FileAppender">
        <param name="file" value="/log/mylogfile.log" />
        <param name="append" value="false" />
        <param name="threshold" value="debug" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
        </layout>
    </appender>

    <appender name="another.file" class="org.apache.log4j.FileAppender">
        <param name="file" value="/log/anotherlogfile.log" />
        <param name="append" value="false" />
        <param name="threshold" value="debug" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{ISO8601} %-5p [%c{1}] - %m%n" />
        </layout>
    </appender>

    <logger name="com.yourcompany.SomeClass" additivity="false">
        <level value="debug" />
        <appender-ref ref="another.file" />
    </logger>

    <root>
        <priority value="info" />
        <appender-ref ref="default.console" />
        <appender-ref ref="default.file" />
    </root>
</log4j:configuration>

使用一个控制台、两个文件附加程序和一个记录器指向第二个文件附加程序而不是第一个。

编辑

在一个较旧的项目中,我发现了一个简单的 log4j.properties 文件:

# For the general syntax of property based configuration files see
# the documentation of org.apache.log4j.PropertyConfigurator.

# The root category uses two appenders: default.out and default.file.
# The first one gathers all log output, the latter only starting with 
# the priority INFO.
# The root priority is DEBUG, so that all classes can be logged unless 
# defined otherwise in more specific properties.
log4j.rootLogger=DEBUG, default.out, default.file

# System.out.println appender for all classes
log4j.appender.default.out=org.apache.log4j.ConsoleAppender
log4j.appender.default.out.threshold=DEBUG
log4j.appender.default.out.layout=org.apache.log4j.PatternLayout
log4j.appender.default.out.layout.ConversionPattern=%-5p %c: %m%n

log4j.appender.default.file=org.apache.log4j.FileAppender
log4j.appender.default.file.append=true
log4j.appender.default.file.file=/log/mylogfile.log
log4j.appender.default.file.threshold=INFO
log4j.appender.default.file.layout=org.apache.log4j.PatternLayout
log4j.appender.default.file.layout.ConversionPattern=%-5p %c: %m%n

所有布局参数的描述请看这里:log4j PatternLayout arguments

【讨论】:

  • 我也要求解释。例如,default-file appender 上的布局参数有什么作用?我可以使用它,但不明白那部分。
  • 它是一种输出模式,那些 % 占位符决定记录哪些信息以及如何格式化这些信息,请查看我稍后将添加到答案中的链接
  • 我有几乎相似的 log4j.xml,但我仍然只在控制台中获取日志,而不是写入文件,尽管正在生成日志文件。只是想问一下这里要添加的所有依赖项和jar。我相信我的 classapth 中有一些相互冲突的罐子。此外,为了获取所有类型的日志,例如信息、错误、调试等,在关卡中应该有什么?
  • 在我的情况下,我只需要在类路径中有 log4j.jar。除非您在代码和 log4j 或自定义附加程序之间使用外观,否则应该足够了。然后将指向您的代码路径的记录器的级别设置为详细的内容,例如debugtrace 甚至all。并将文件 appender 的 threshold 参数设置为相同的值。
【解决方案2】:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false">

   <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
      <param name="Threshold" value="INFO" />
      <param name="File" value="sample.log"/>
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d %-5p  [%c{1}] %m %n" />
      </layout>
   </appender>

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

</log4j:configuration>

Log4j 可能有点混乱。因此,让我们尝试了解此文件中发生的情况: 在 log4j 中,您有两个基本构造 appenders 和 loggers。

Appenders 定义追加内容的方式和位置。它会被记录到文件、控制台、数据库等吗?在这种情况下,您指定将使用 layout 标记中指定的模式将定向到 fileAppender 的日志语句放入文件 sample.log。您可以轻松地为控制台或数据库创建附加程序。控制台附加程序将指定诸如屏幕上的布局之类的内容,而数据库附加程序将具有连接详细信息和表名。

记录器在记录事件冒泡时对其作出响应。如果一个事件引起了特定记录器的兴趣,它将调用其附加的附加程序。在下面的示例中,您只有一个记录器,即根记录器 - 默认情况下响应所有记录事件。除了根记录器之外,您还可以指定更具体的记录器来响应来自特定包的事件。这些记录器可以使用appender-ref 标签指定它们自己的附加程序,或者以其他方式从根记录器继承附加程序。使用更具体的记录器允许您微调特定包的日志记录级别或将某些包定向到其他附加程序。

所以这个文件的意思是:

  1. 创建一个 fileAppender 记录到 文件 sample.log
  2. 将该附加程序附加到根 记录器。
  3. 根记录器将响应任何 事件至少与 “调试”级别
  4. 附加程序配置为仅 记录至少为 详细为“信息”

最终结果是,如果您的代码中有logger.debug("blah blah"),它将被忽略。 logger.info("Blah blah"); 将输出到 sample.log。

下面的 sn-p 可以用 log4j 标签添加到上面的文件中。此记录器将从&lt;root&gt; 继承附加程序,但会将包org.springframework 中的所有记录事件限制为记录在info 或更高级别的事件。

  <!-- Example Package level Logger -->
    <logger name="org.springframework">
        <level value="info"/>
    </logger>   

【讨论】:

  • 将在哪里创建文件 sample.log?
  • 我认为这是一个很大的依赖。在容器之外,我相信这会将日志文件放在您的 CWD 中,但是如果您在容器中配置日志记录,则容器可能会将其放在其他地方。
【解决方案3】:

这里有一个我经常使用的简单的:

# Set up logging to include a file record of the output
# Note: the file is always created, even if there is 
# no actual output.
log4j.rootLogger=error, stdout, R

# Log format to standard out
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=   %5p\t[%d] [%t] (%F:%L)\n     \t%m%n\n

# File based log output
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=owls_conditions.log
log4j.appender.R.MaxFileSize=10000KB
# Keep one backup file
log4j.appender.R.MaxBackupIndex=1
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=   %5p\t[%d] [%t] (%F:%L)\n     \t%m%n\n

日志格式如下:

ERROR   [2009-09-13 09:56:01,760] [main] (RDFDefaultErrorHandler.java:44)
        http://www.xfront.com/owl/ontologies/camera/#(line 1 column 1): Content is not allowed in prolog.

这种格式由字符串%5p\t[%d] [%t] (%F:%L)\n \t%m%n\n 定义。您可以在log4j javadoc for PatternLayout中阅读转换字符的含义。

包含的 cmets 应该有助于理解它的作用。补充说明:

  • 它同时记录到控制台和文件;在这种情况下,文件名为owls_conditions.log:根据您的需要进行更改;
  • 文件达到 10000KB 时进行轮换,并保留一个备份文件

【讨论】:

    【解决方案4】:

    这是一个我已经成功使用的 log4j.properties 文件。

    logDir=/var/log/myapp
    
    log4j.rootLogger=INFO, stdout
    #log4j.rootLogger=DEBUG, stdout
    
    log4j.appender.stdout=org.apache.log4j.DailyRollingFileAppender
    log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern=%d{MM/dd/yyyy hh:mm:ss a}|%-5p|%-30c{1}| %m%n
    log4j.appender.stdout.DatePattern='.'yyyy-MM-dd
    log4j.appender.stdout.File=${logDir}/myapp.log
    log4j.appender.stdout.append=true
    

    DailyRollingFileAppender 每天都会创建新文件,文件名如下所示:

    myapp.log.2017-01-27
    myapp.log.2017-01-28
    myapp.log.2017-01-29
    myapp.log  <-- today's log
    

    日志文件中的每个条目都将采用以下格式:

    01/30/2017 12:59:47 AM|INFO |Component1   | calling foobar(): userId=123, returning totalSent=1
    01/30/2017 12:59:47 AM|INFO |Component2   | count=1 > 0, calling fooBar()
    

    使用-Dlog4j.configuration设置上述文件的位置,如this posting中所述:

    java -Dlog4j.configuration=file:/home/myapp/config/log4j.properties com.foobar.myapp
    

    在您的 Java 代码中,当您实例化您的记录器对象时,请务必设置每个软件组件的名称。我也喜欢同时记录到日志文件和标准输出,所以我写了这个小函数。

    private static final Logger LOGGER = Logger.getLogger("Component1");
    
    public static void log(org.apache.log4j.Logger logger, String message) {
    
        logger.info(message);
        System.out.printf("%s\n", message);
    }
    
    public static String stackTraceToString(Exception ex) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        ex.printStackTrace(pw);
        return sw.toString();
    }
    

    然后这样称呼它:

    LOGGER.info(String.format("Exception occurred: %s", stackTraceToString(ex)));
    

    【讨论】:

      猜你喜欢
      • 2010-09-30
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      • 2010-09-22
      相关资源
      最近更新 更多