我的故事:
我想做一个像最简单的log4j记录器一样简单的东西,它将行记录到一个文件中。我发现了几个具有一些功能的例子,但不是一个真正有效的基本的、通用的例子,也没有一个解释每一行是如何工作的。
问题:
有人能提供一个吗?
先决条件:
- 我已经知道该把文件放在哪里了,并且我已经配置了log4j,并且正在为控制台日志记录工作
- 现在我想登录到一个文件,并在程序运行后从文件系统中找到该文件
- 需要添加到现有
log4j.properties
文件中的行是所需的输出
我有一个通用的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
<?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和logger。
附加符定义附加内容的方式和位置。它会被记录到文件、控制台、数据库等中吗。?在这种情况下,指定指向fileAppender的日志语句将使用layout标记中指定的模式放入文件sample.log
中。您可以很容易地为控制台或数据库创建一个appender。控制台appender将指定屏幕上的布局等内容,而数据库appender则具有连接详细信息和表名。
日志程序在日志事件出现气泡时对其作出响应。如果某个事件引起了特定记录器的兴趣,它将调用其附加的附加程序。在下面的示例中,您只有一个记录器-根记录器-默认情况下,它会响应所有日志事件。除了根记录器之外,您还可以指定更具体的记录器来响应特定包中的事件。这些记录器可以使用appender-ref
标记指定自己的附加程序,也可以从根记录器继承附加程序。使用更具体的记录器可以微调特定包的日志记录级别,或者将某些包定向到其他附加程序。
所以这个文件说的是:
- 创建一个登录到的fileAppender文件sample.log
- 将附加程序附加到根记录器
- 根记录器将响应任何事件至少详细到"调试"级别
- appender配置为仅记录至少为详细信息为"信息"
净结果是,如果你的代码中有一个logger.debug("blah blah")
,它将被忽略。logger.info("Blah blah");
将输出到sample.log。
可以使用log4j标记将下面的代码段添加到上面的文件中。此记录器将继承来自<root>
的appenders,但将把来自包org.springframework
的所有日志记录事件限制为在级别info
或更高级别记录的事件。
<!-- Example Package level Logger -->
<logger name="org.springframework">
<level value="info"/>
</logger>
这里有一个我经常使用的简单方法:
# 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= %5pt[%d] [%t] (%F:%L)n t%m%nn
# 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= %5pt[%d] [%t] (%F:%L)n t%m%nn
日志的格式如下:
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.
这样的格式由字符串CCD_ 9来定义。您可以在log4jjavadoc中读取PatternLayout
的转换字符的含义。
包含的评论应该有助于理解它的作用。进一步说明:
- 它同时登录到控制台和文件;在这种情况下,文件名为
owls_conditions.log
:根据您的需要进行更改 - 文件在达到10000KB时进行轮换,并保留一个备份文件
这里有一个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
设置上述文件的位置:
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("%sn", 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)));