- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 java 1.7 中使用 log4j2 (beta9)。
我完整的 log4j2.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>
我想在每个日志文件的顶部添加一些自定义信息,例如我的应用程序的版本字符串、应用程序正常运行时间和系统正常运行时间。甚至在刚刚关闭的日志文件的底部写一些 »bye, bye/eof« 也可以。
当 RollingFileAppander 创建了一个新文件时,是否有类似钩子(Hook)或回调的东西来得到通知,以便我可以首先将我的东西放入这些新日志文件(或任何其他建议)?
最佳答案
好的,通过像 here 中描述的那样扩展 DefaultRolloverStrategy,可以解决这个问题。 .但是
要让log4j2调用我们的工厂方法,log4j2.xml的根标签必须带有我们类的包属性,例如:
<Configuration packages="de.jme.toolbox.logging">
...
</Configuration>
在我们自己的 RolloverStrategy 中,我们必须处理 @Plugin
和 @PluginFactory
,如 here 所述.
最后是我完整的 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>
这里是 MyRolloverStrategy.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);
}
}
如果我发布了 feature request,那么在 log4j2 的 future 版本中解决这个要求可能会更容易将实现。
关于java - Log4j2 RollingFile Appender - 在每个日志文件的开头添加自定义信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20819376/
好的,所以我编辑了以下... 只需将以下内容放入我的 custom.css #rt-utility .rt-block {CODE HERE} 但是当我尝试改变... 与 #rt-sideslid
在表格 View 中,我有一个自定义单元格(在界面生成器中高度为 500)。在该单元格中,我有一个 Collection View ,我按 (10,10,10,10) 固定到边缘。但是在 tablev
对于我的无能,我很抱歉,但总的来说,我对 Cocoa、Swift 和面向对象编程还很陌生。我的主要来源是《Cocoa Programming for OS X》(第 5 版),以及 Apple 的充满
我正在使用 meta-tegra 为我的 NVIDIA Jetson Nano 构建自定义图像。我需要 PyTorch,但没有它的配方。我在设备上构建了 PyTorch,并将其打包到设备上的轮子中。现
在 jquery 中使用 $.POST 和 $.GET 时,有没有办法将自定义变量添加到 URL 并发送它们?我尝试了以下方法: $.ajax({type:"POST", url:"file.php?
Traefik 已经默认实现了很多中间件,可以满足大部分我们日常的需求,但是在实际工作中,用户仍然还是有自定义中间件的需求,为解决这个问题,官方推出了一个 Traefik Pilot[1] 的功
我想让我的 CustomTextInputLayout 将 Widget.MaterialComponents.TextInputLayout.OutlinedBox 作为默认样式,无需在 XML 中
我在 ~/.emacs 中有以下自定义函数: (defun xi-rgrep (term) (grep-compute-defaults) (interactive "sSearch Te
我有下表: 考虑到每个月的权重,我的目标是在 5 个月内分散 10,000 个单位。与 10,000 相邻的行是我最好的尝试(我在这上面花了几个小时)。黄色是我所追求的。 我试图用来计算的逻辑如下:计
我的表单中有一个字段,它是文件类型。当用户点击保存图标时,我想自然地将文件上传到服务器并将文件名保存在数据库中。我尝试通过回显文件名来测试它,但它似乎不起作用。另外,如何将文件名添加到数据库中?是在模
我有一个 python 脚本来发送电子邮件,它工作得很好,但问题是当我检查我的电子邮件收件箱时。 我希望该用户名是自定义用户名,而不是整个电子邮件地址。 最佳答案 发件人地址应该使用的格式是: You
我想减小 ggcorrplot 中标记的大小,并减少文本和绘图之间的空间。 library(ggcorrplot) data(mtcars) corr <- round(cor(mtcars), 1)
GTK+ noob 问题在这里: 是否可以自定义 GtkFileChooserButton 或 GtkFileChooserDialog 以删除“位置”部分(左侧)和顶部的“位置”输入框? 我实际上要
我正在尝试在主页上使用 ajax 在 magento 中使用 ajax 显示流行的产品列表,我可以为 5 或“N”个产品执行此操作,但我想要的是将分页工具栏与结果集一起添加. 这是我添加的以显示流行产
我正在尝试使用 PasswordResetForm 内置函数。 由于我想要自定义表单字段,因此我编写了自己的表单: class FpasswordForm(PasswordResetForm):
据我了解,新的 Angular 7 提供了拖放功能。我搜索了有关 DnD 的 Tree 组件,但没有找到与树相关的内容。 我在 Stackblitz 上找到的一个工作示例.对比drag'ndrop功能
我必须开发一个自定义选项卡控件并决定使用 WPF/XAML 创建它,因为我无论如何都打算学习它。完成后应该是这样的: 到目前为止,我取得了很好的进展,但还有两个问题: 只有第一个/最后一个标签项应该有
我要定制xtable用于导出到 LaTeX。我知道有些问题是关于 xtable在这里,但我找不到我要找的具体东西。 以下是我的表的外观示例: my.table <- data.frame(Specif
用ejs在这里显示日期 它给我结果 Tue Feb 02 2016 16:02:24 GMT+0530 (IST) 但是我需要表现为 19th January, 2016 如何在ejs中执行此操作?
我想问在 JavaFX 中使用自定义对象制作 ListView 的最佳方法,我想要一个每个项目如下所示的列表: 我搜了一下,发现大部分人都是用细胞工厂的方法来做的。有没有其他办法?例如使用客户 fxm
我是一名优秀的程序员,十分优秀!