因此,正如大多数人尝试做的那样,我尝试扩展Log4j2中的“ AbstractExtender”。但是,当我加载程序时,出现以下错误:“ FooAppender包含无效的元素或属性“ fileName” ”。现在,我对任何编程都不陌生,我知道我需要以某种方式实现filename属性。但是我对如何实际做到这一点感到困惑。这是我的代码和配置-我被困在如何将filename属性传递到正确的位置。提前很多帮助为您服务! :)
package my.appenders;
import java.io.Serializable;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.appender.FileAppender;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.PatternLayout;
// note: class name need not match the @Plugin name.
@Plugin(name = "FooAppender", category = "Core", elementType = "appender", printObject = true)
public final class FooAppender extends AbstractAppender
{
private final ReadWriteLock rwLock = new ReentrantReadWriteLock();
private final Lock readLock = rwLock.readLock();
protected FooAppender(String name, String fileName, Filter filter, Layout<? extends Serializable> layout,
final boolean ignoreExceptions)
{
super(name, filter, layout, ignoreExceptions);
}
// The append method is where the appender does the work.
// Given a log event, you are free to do with it what you want.
// This example demonstrates:
// 1. Concurrency: this method may be called by multiple threads concurrently
// 2. How to use layouts
// 3. Error handling
@Override
public void append(LogEvent event)
{
readLock.lock();
try
{
final byte[] bytes = getLayout().toByteArray(event);
System.out.write(bytes);
} catch (Exception ex)
{
if (!ignoreExceptions())
{
throw new AppenderLoggingException(ex);
}
} finally
{
readLock.unlock();
}
}
// Your custom appender needs to declare a factory method
// annotated with `@PluginFactory`. Log4j will parse the configuration
// and call this factory method to construct an appender instance with
// the configured attributes.
@PluginFactory
public static FooAppender createAppender(
@PluginAttribute("name") String name,
@PluginAttribute("fileName") String fileName,
@PluginElement("Layout") Layout<? extends Serializable> layout,
@PluginElement("Filter") final Filter filter, @PluginAttribute("otherAttribute") String otherAttribute)
{
if (name == null)
{
LOGGER.error("No name provided for FooAppender");
return null;
}
if (layout == null)
{
layout = PatternLayout.createDefaultLayout();
}
return new FooAppender(name, fileName, filter, layout, true);
}
}
和配置:
<?xml version="1.0" encoding="utf-8"?>
<Configuration debug="true" status="trace" packages="my.appenders">
<Properties>
<Property name="logPath">E:\Code\Workspace_Java\Log4jTest\bin</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="default.log"
fileName="${logPath}/SignatureVerifier_${date:yyyy-MM-dd-HH-mm-ss}.log">
<PatternLayout>
<pattern>%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</PatternLayout>
</File >
<FooAppender name="debug.log"
fileName="${logPath}/Debug_${date:yyyy-MM-dd-HH-mm-ss}.log">
<PatternLayout>
<pattern>%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
</PatternLayout>
</FooAppender >
</Appenders>
<Loggers>
<Root level="TRACE">
<AppenderRef ref="Console" Level="INFO" />
<AppenderRef ref="default.log" Level="INFO"/>
<Appender-ref ref="debug.log" Level="ALL"/>
</Root>
</Loggers>
</Configuration>