在java 1.7中使用log4j2(beta9)。
我的完整日志4J2。xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="projectPrefix">Tts</Property>
<Property name="rawPattern">%d %-5p [%t] %C{2} (%F:%L) - %m%n</Property>
<Property name="coloredPattern">%d %highlight{%-5p}{FATAL=bright red, ERROR=red, WARN=yellow, INFO=cyan, DEBUG=green, TRACE=bright blue} %style{[%t] %C{2} (%F:%L) -}{bright,black} %m%n</Property>
<Property name="fileName">Log/${projectPrefix}.log</Property>
<Property name="filePattern">Log/${projectPrefix}-%i.log</Property>
</Properties>
<Appenders>
<Console name="Stdout" target="SYSTEM_OUT">
<PatternLayout pattern="${coloredPattern}"/>
</Console>
<RollingFile name="Logfile" fileName="${fileName}" filePattern="${filePattern}">
<PatternLayout pattern="${rawPattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="16 MB"/>
</Policies>
<DefaultRolloverStrategy fileIndex="min" max="16"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Stdout"/>
<AppenderRef ref="Logfile"/>
</Root>
</Loggers>
</Configuration>
我想在每个日志文件的顶部添加一些自定义信息,如我的应用程序的版本字符串、应用程序正常运行时间和系统正常运行时间。甚至在刚刚关闭的日志文件的底部写一些»再见,再见/eof«也可以。
当RollingFileAppander创建了一个新文件时,是否有类似于钩子或回调的东西可以得到通知,以便我可以首先将我的东西放入这些新的日志文件(或任何其他建议)?
目前没有用于翻转的回调挂钩。我可以建议将其作为log4j2问题跟踪器中的功能请求提出吗?
可用的新解决方案
自从这个问题被提出以来已经过去了一段时间,现在,当我想做同样的事情时,我发现可以在不干扰工厂的情况下解决,但这并不容易找到。log4j2团队通过配置使这成为可能。我希望我的帖子会有用,并为其他人节省时间。
他们在PatternLayout元素中隐藏了此功能。不是我第一次看的地方,但它起作用了,为什么还要抱怨呢?
这是我的配置(请注意页眉和页脚及其使用的属性):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="log-path">${sys:catalina.home}/logs/my-app</Property>
<Property name="archive">${log-path}/archive</Property>
<Property name="defaultPattern">[%d] [%-5p] [%t] %C{5} - %m%n</Property>
<Property name="defaultRollOverMax">450</Property>
<Property name="fileHeader">[%d] Start of log \n========================================================================\n
Will be archived in ${archive}\n\n</Property>
<Property name="fileFooter">\n========================================================================\n[%d] End of log</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="%highlight{[%d] [%-5p] [%t] %C{3} (%F:%L) - %m%n}" charset="UTF-8"/>
</Console>
<RollingFile name="Root"
fileName="${log-path}/root.log"
filePattern="${archive}/root.log.%d{yyyy-MM-dd}_%i.gz"
immediateFlush="true">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<PatternLayout pattern="${defaultPattern}"
charset="UTF-8"
header="This is the ROOT logger and it should be silent \n - define loggers when you see something in here"
footer="Closing"/>
<DefaultRolloverStrategy max="${defaultRollOverMax}" fileIndex="max"/>
</RollingFile>
<RollingFile name="System"
fileName="${log-path}/system.log"
filePattern="${archive}/system.log.%d{yyyy-MM-dd}_%i.gz"
immediateFlush="true">
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY" />
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<PatternLayout pattern="${defaultPattern}"
charset="UTF-8"
header="${fileHeader}"
footer="${fileFooter}"/>
<DefaultRolloverStrategy max="${defaultRollOverMax}" fileIndex="max"/>
</RollingFile>
<RollingFile name="Error"
fileName="${log-path}/error.log"
filePattern="${archive}/error.log.%d{yyyy-MM-dd}_%i.gz"
immediateFlush="true">
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<PatternLayout pattern="${defaultPattern}"
charset="UTF-8"
header="${fileHeader}"
footer="${fileFooter}"/>
<DefaultRolloverStrategy max="${defaultRollOverMax}" fileIndex="max"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="org.myOrganization.myApplication" additivity="false" level="INFO">
<appender-ref ref="System"/>
<appender-ref ref="Console"/>
<appender-ref ref="Error"/>
</Logger>
<Logger name="org.myOrganization.myApplication.peculiarPackage" additivity="false" level="TRACE">
<appender-ref ref="System"/>
<appender-ref ref="Console"/>
<appender-ref ref="Error"/>
</Logger>
<Logger name="org.springframework" additivity="false" level="WARN">
<appender-ref ref="System"/>
<appender-ref ref="Console"/>
<appender-ref ref="Error"/>
</Logger>
<Logger name="javax" additivity="false" level="WARN">
<appender-ref ref="System"/>
<appender-ref ref="Console"/>
<appender-ref ref="Error"/>
</Logger>
<!-- Root logger should be empty -->
<Root level="all">
<AppenderRef ref="Root"/>
<AppenderRef ref="Console"/>
<!--Make sure all errors are logged to the error log-->
<appender-ref ref="Error"/>
</Root>
</Loggers>
</Configuration>
如您所见,我包含了一个时间戳和一个属性,其中包括一个系统属性。Log4j2可以显示许多不同类型的属性,通过它,您可以按照自己的要求完成很多事情。
日志文件如下所示:
[2016-08-09 17:00:43,924] Start of log
========================================================================
Will be archived in /home/emanciperingsivraren/program/apache-tomcat-8.0.32/logs/my-app/archive
[2016-08-09 17:00:44,000] [INFO ] [RMI TCP Connection(2)-127.0.0.1] [snip]
========================================================================
[2016-08-09 17:02:17,871] End of log
您需要更多自定义信息吗?-尝试将该信息放在属性、系统属性或log4j2可以读取的其他内容中。
有关您可以拥有的属性类型的详细信息,请参阅log4j2中的属性替换。
关于配置的注释
好的,通过像这里描述的那样扩展DefaultRolloverStrategy,可以有效地解决这个问题。但是
为了让log4j2调用我们的工厂方法,log4j2的根标记。xml必须与我们类的包一起归属,例如:
<Configuration packages="de.jme.toolbox.logging">
...
</Configuration>
在我们自己的滚动策略中,我们必须处理这里描述的插件和插件。
最后在这里我完整的log4j2.xml(你不需要所有的属性-这只是我喜欢如何配置我的日志):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="de.jme.toolbox.logging">
<Properties>
<Property name="projectPrefix">Tts</Property>
<Property name="rawPattern">%d %-5p [%t] %C{2} (%F:%L) - %m%n</Property>
<Property name="coloredPattern">%d %highlight{%-5p}{FATAL=bright red, ERROR=red, WARN=yellow, INFO=cyan, DEBUG=green, TRACE=bright blue} %style{[%t] %C{2} (%F:%L) -}{bright,black} %m%n</Property>
<Property name="coloredShortPattern">%d %highlight{%-5p}{FATAL=bright red, ERROR=red, WARN=yellow, INFO=cyan, DEBUG=green, TRACE=bright blue} %style{[%t] -}{bright,black} %m%n</Property>
<Property name="fileName">Log/${projectPrefix}.log</Property>
<Property name="filePattern">Log/${projectPrefix}-%i.log</Property>
</Properties>
<Appenders>
<Console name="Stdout" target="SYSTEM_OUT">
<PatternLayout pattern="${coloredPattern}"/>
</Console>
<RollingFile name="Logfile" fileName="${fileName}" filePattern="${filePattern}">
<PatternLayout pattern="${rawPattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="1 MB"/>
</Policies>
<MyRolloverStrategy fileIndex="min" max="16"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Stdout"/>
<AppenderRef ref="Logfile"/>
</Root>
</Loggers>
</Configuration>
这是我的滚动策略。java:
package de.jme.toolbox.logging;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.zip.Deflater;
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
import org.apache.logging.log4j.core.appender.rolling.RolloverDescription;
import org.apache.logging.log4j.core.appender.rolling.helper.Action;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.helpers.Integers;
import org.apache.logging.log4j.core.lookup.StrSubstitutor;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.status.StatusLogger;
/**
* Own RolloverStrategy to hook the DefaultRolloverStrategy's rollover events
*
* Siehe auch:
* - https://issues.apache.org/jira/browse/LOG4J2-486
* - http://apache-logging.6191.n7.nabble.com/log4j2-getting-started-amp-rolling-files-tt8406.html#a42402
* - http://stackoverflow.com/questions/20819376/log4j2-rollingfile-appender-add-custom-info-at-the-start-of-each-logfile
*
* @author Joe Merten
*/
@org.apache.logging.log4j.core.config.plugins.Plugin(name="MyRolloverStrategy", category="Core", printObject=true)
public class MyRolloverStrategy extends DefaultRolloverStrategy {
protected static final Logger logger = StatusLogger.getLogger();
// ==============================
// ↓↓↓ Some stuff copied from ↓↓↓
// https://svn.apache.org/repos/asf/logging/log4j/log4j2/trunk/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/rolling/DefaultRolloverStrategy.java r1556050
// Just changed »DefaultRolloverStrategy« to »MyRolloverStrategy«
private static final int MIN_WINDOW_SIZE = 1;
private static final int DEFAULT_WINDOW_SIZE = 7;
@PluginFactory
public static MyRolloverStrategy createStrategy(
@PluginAttribute("max") final String max,
@PluginAttribute("min") final String min,
@PluginAttribute("fileIndex") final String fileIndex,
@PluginAttribute("compressionLevel") final String compressionLevelStr,
@PluginConfiguration final Configuration config) {
final boolean useMax = fileIndex == null ? true : fileIndex.equalsIgnoreCase("max");
int minIndex;
if (min != null) {
minIndex = Integer.parseInt(min);
if (minIndex < 1) {
LOGGER.error("Minimum window size too small. Limited to " + MIN_WINDOW_SIZE);
minIndex = MIN_WINDOW_SIZE;
}
} else {
minIndex = MIN_WINDOW_SIZE;
}
int maxIndex;
if (max != null) {
maxIndex = Integer.parseInt(max);
if (maxIndex < minIndex) {
maxIndex = minIndex < DEFAULT_WINDOW_SIZE ? DEFAULT_WINDOW_SIZE : minIndex;
LOGGER.error("Maximum window size must be greater than the minimum windows size. Set to " + maxIndex);
}
} else {
maxIndex = DEFAULT_WINDOW_SIZE;
}
final int compressionLevel = Integers.parseInt(compressionLevelStr, Deflater.DEFAULT_COMPRESSION);
return new MyRolloverStrategy(minIndex, maxIndex, useMax, compressionLevel, config.getStrSubstitutor());
}
// ↑↑↑ Some stuff copied from ↑↑↑
// ==============================
protected MyRolloverStrategy(int minIndex, int maxIndex, boolean useMax, int compressionLevel, StrSubstitutor subst) {
super(minIndex, maxIndex, useMax, compressionLevel, subst);
}
// Wrapper class only for setting a hook to execute()
static class MyAction implements Action {
final Action delegate;
final String fileName;
public MyAction(final Action delegate, final String fileName) {
this.delegate = delegate;
this.fileName = fileName;
}
@Override public void run() {
delegate.run();
}
@Override public boolean execute() throws IOException {
try {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(new File(fileName), true));
writer.write("****************************\n");
writer.write("*** Bye, bye old logfile ***\n");
writer.write("****************************\n");
} finally {
if (writer != null)
writer.close();
}
} catch (Throwable e) {
logger.error("Writing to bottom of old logfile \"" + fileName + "\" with", e);
}
boolean ret = delegate.execute();
try {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(new File(fileName), true));
writer.write("*************************\n");
writer.write("*** Hello new logfile ***\n");
writer.write("*************************\n");
} finally {
if (writer != null)
writer.close();
}
} catch (Throwable e) {
logger.error("Writing to top of new logfile \"" + fileName + "\" with", e);
}
return ret;
}
@Override public void close() {
delegate.close();
}
@Override public boolean isComplete() {
return delegate.isComplete();
}
}
// Wrapper class only for setting a hook to getSynchronous().execute()
static class MyRolloverDescription implements RolloverDescription {
final RolloverDescription delegate;
public MyRolloverDescription(final RolloverDescription delegate) {
this.delegate = delegate;
}
@Override public String getActiveFileName() {
return delegate.getActiveFileName();
}
@Override public boolean getAppend() {
//return delegate.getAppend();
// As long as we already put some data to the top of the new logfile, subsequent writes should be performed with "append".
return true;
}
// The synchronous action is for renaming, here we want to hook
@Override public Action getSynchronous() {
Action delegateAction = delegate.getSynchronous();
if (delegateAction == null) return null;
return new MyAction(delegateAction, delegate.getActiveFileName());
}
// The asynchronous action is for compressing, we don't need to hook here
@Override public Action getAsynchronous() {
return delegate.getAsynchronous();
}
}
public RolloverDescription rollover(final RollingFileManager manager) {
RolloverDescription ret = super.rollover(manager);
return new MyRolloverDescription(ret);
}
}
如果我发布的功能请求能够实现,在log4j2的未来版本中解决这个要求可能会更容易。
问题内容: 在Java 1.7中使用log4j2(beta9)。 我完整的log4j2.xml: 我想在每个日志文件的顶部添加一些自定义信息,例如我的应用程序的版本字符串,应用程序正常运行时间和系统正常运行时间。甚至将“再见,再见/ eof”写到刚刚关闭的日志文件的底部也可以。 在RollingFileAppander创建新文件时,是否有类似钩子或回调的通知得到通知,以便我可以首先将东西放入这些新
我已经从其中一个服务复制了swagger.json文件,并想将其导入到Postman collection中
本文向大家介绍magento 自定义日志文件,包括了magento 自定义日志文件的使用技巧和注意事项,需要的朋友参考一下 示例 这将登录到
我一直在找,但还是想不出来。我需要为日志输出添加一个自定义日志模式。通过resources目录中的logback.xml文件,我可以非常轻松地完成此操作,而且它完全按照我所希望的方式工作。 但是,如果可能的话,我希望能够在整个application.yml文件中这样做。主要是因为我想把它外化在一个地方。
问题内容: 我想为我的应用程序使用loglevel TRACE(5),因为我认为这还不够。另外不是我想要的。如何将自定义日志级别添加到Python记录器? 我有以下内容: 在我的代码中,我通过以下方式使用它: 现在我想打电话 在此先感谢您的帮助。 编辑 (2016年12月8日):我[pfa的)可接受答案更改为IMHO,这是基于Eric S的非常好的建议的出色解决方案。 问题答案: @Eric S.
我试图建立一个应用程序,使用log4j使日志文件。日志文件的位置通过log4j.properties文件提供。 到目前为止,它运行良好,但我想将spark日志与我从代码生成的日志分开。或者至少在日志文件中打印我的日志消息。 有办法吗? log4j.properties