Java Log4j:如何配置最简单的文件日志记录?

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

Log4j: How to configure simplest possible file logging?

javalogginglog4j

提问by mico

My story:

我的故事:

I want to make a thing which is as simple as a simplest possible log4j logger that logs rows to a file. I have found several examples with some functionality, but not a basic, general one that really works, and not one with an explanation how the each row work.

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

Question:

题:

Could anybody provide one?

有人可以提供一份吗?

Prerequisites:

先决条件:

  • I already know where to put the file and I have the log4j configured and working for console logging.
  • Now I want to log to a file and also find the file from file system once the program has run.
  • Rows needed to be added to the existing log4j.propertiesfile are the desired output.
  • 我已经知道将文件放在哪里,并且我已经配置了 log4j 并用于控制台日志记录。
  • 现在我想登录到一个文件,并在程序运行后从文件系统中找到该文件。
  • 需要添加到现有log4j.properties文件的行是所需的输出。

采纳答案by Tomasz Stanczak

I have one generic log4j.xml file for you:

我有一个通用的 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>

with one console, two file appender and one logger poiting to the second file appender instead of the first.

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

EDIT

编辑

In one of the older projects I have found a simple log4j.properties file:

在一个较旧的项目中,我发现了一个简单的 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

For the description of all the layout arguments look here: log4j PatternLayout arguments

有关所有布局参数的说明,请查看此处:log4j PatternLayout arguments

回答by MarcoS

Here's a simple one that I often use:

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

# 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

The format of the log is as follows:

日志的格式如下:

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.

Such a format is defined by the string %5p\t[%d] [%t] (%F:%L)\n \t%m%n\n. You can read the meaning of conversion characters in log4j javadoc for PatternLayout.

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

Included comments should help in understanding what it does. Further notes:

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

  • it logs both to console and to file; in this case the file is named owls_conditions.log: change it according to your needs;
  • files are rotated when they reach 10000KB, and one back-up file is kept
  • 它同时记录到控制台和文件;在这种情况下,文件被命名为owls_conditions.log:根据您的需要更改它;
  • 文件达到10000KB时进行轮换,并保留一个备份文件

回答by nsfyn55

<?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 can be a bit confusing. So lets try to understand what is going on in this file: In log4j you have two basic constructs appenders and loggers.

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

Appendersdefine how and where things are appended. Will it be logged to a file, to the console, to a database, etc.? In this case you are specifying that log statements directed to fileAppender will be put in the file sample.logusing the pattern specified in the layouttags. You could just as easily create a appender for the console or the database. Where the console appender would specify things like the layout on the screen and the database appender would have connection details and table names.

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

Loggersrespond to logging events as they bubble up. If an event catches the interest of a specific logger it will invoke its attached appenders. In the example below you have only one logger the root logger - which responds to all logging events by default. In addition to the root logger you can specify more specific loggers that respond to events from specific packages. These loggers can have their own appenders specified using the appender-reftags or will otherwise inherit the appenders from the root logger. Using more specific loggers allows you to fine tune the logging level on specific packages or to direct certain packages to other appenders.

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

So what this file is saying is:

所以这个文件说的是:

  1. Create a fileAppender that logs to file sample.log
  2. Attach that appender to the root logger.
  3. The root logger will respond to any events at least as detailed as 'debug' level
  4. The appender is configured to only log events that are at least as detailed as 'info'
  1. 创建一个记录到文件 sample.log 的 fileAppender
  2. 将该附加程序附加到根记录器。
  3. 根记录器将响应至少与“调试”级别一样详细的任何事件
  4. appender 配置为仅记录至少与“信息”一样详细的事件

The net out is that if you have a logger.debug("blah blah")in your code it will get ignored. A logger.info("Blah blah");will output to sample.log.

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

The snippet below could be added to the file above with the log4jtags. This logger would inherit the appenders from <root>but would limit the all logging events from the package org.springframeworkto those logged at level infoor above.

下面的代码片段可以使用log4j标签添加到上面的文件中。这个记录器将继承 appender,<root>但会将包中的所有日志记录事件限制为org.springframework在级别info或更高级别记录的事件。

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

回答by stackoverflowuser2010

Here is a log4j.properties file that I've used with great success.

这是我使用的非常成功的 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

The DailyRollingFileAppender will create new files each day with file names that look like this:

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

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

Each entry in the log file will will have this format:

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

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()

Set the location of the above file by using -Dlog4j.configuration, as mentioned in this posting:

使用 设置上述文件的位置-Dlog4j.configuration,如本帖所述

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

In your Java code, be sure to set the name of each software component when you instantiate your logger object. I also like to log to both the log file and standard output, so I wrote this small function.

在 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();
}

And then call it like so:

然后像这样调用它:

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