我扩展了log42记录器.
想法:
我应该将枚举传递给log方法,以便在运行时选择appender.
我的界面:
public interface MyLoggerInterface {
void info(String logMessage, MyLoggerAppenderEnum... appender);
public static MyLoggerInterface getLogger(Class aClass, MyLoggerAppenderEnum... appender) {
return MyLoggerInterfaceImpl.getLogger(aClass, appender);
}
}
执行:
public class MyLoggerInterfaceImpl extends Logger implements MyLoggerInterface {
private static final String FQCN = MyLoggerInterfaceImpl.class.getName();
protected MyLoggerInterfaceImpl(LoggerContext context, String name, MessageFactory messageFactory) {
super(context, name, messageFactory);
}
public static MyLoggerInterface getLogger(Class aClass, MyLoggerAppenderEnum... appenders) {
return getLogger(aClass.getName(), appenders);
}
private static MyLoggerInterface getLogger(String name, MyLoggerAppenderEnum... appenders) {
return (MyLoggerInterfaceImpl) org.apache.logging.log4j.LogManager.getLogger(name);
}
@Override
public void info(String logMessage, MyLoggerAppenderEnum... appenders) {
this.log(FQCN, Level.INFO, null, new SimpleMessage(logMessage), null, appenders);
}
private void log(String fqcn, Level level, Marker marker, Message message, Throwable throwable, MyLoggerAppenderEnum... appenders) {
Arrays.stream(appenders)
.map(appender -> findAppenderByName(appender))
.collect(Collectors.toList())
.forEach(appender ->
appender.append(
new Log4jLogEvent(this.getName(), marker, fqcn, level, message, new ArrayList(), throwable)
)
);
}
private Appender findAppenderByName(MyLoggerAppenderEnum appenders) {
return this.getAppenders().get(appenders.name());
}
}
但请注意,在log4j 2.X中,LoggerFactory已从1.X版本中删除.所以我实现了其他类,以避免ClassCastException(Logger to MyLoggerInterfaceImpl).
所以. MyContext:
public class MyLoggerContext extends LoggerContext {
public MyLoggerContext(String name) {
super(name);
}
@Override
protected Logger newInstance(final LoggerContext ctx, final String name, final MessageFactory messageFactory) {
return new MyLoggerInterfaceImpl(ctx, name, messageFactory);
}
}
上下文选择器:
public class MyLoggerContextSelector implements ContextSelector {
private final LoggerContext CONTEXT = new MyLoggerContext("MyLoggerContext");
public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext) {
return CONTEXT;
}
public LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation) {
return CONTEXT;
}
public List getLoggerContexts() {
return Arrays.asList(CONTEXT);
}
public void removeContext(LoggerContext context) {
}
}
上下文工厂:
public class MyLoggerLog4jContextFactory extends Log4jContextFactory {
public MyLoggerLog4jContextFactory() {
super(new MyLoggerContextSelector(), new DefaultShutdownCallbackRegistry());
}
}
和经理:
public class MyLoggerManager {
public static void initialize(String configURL) {
try {
System.setProperty("log4j2.loggerContextFactory", "ge.test.core.logging.MyLoggerLog4jContextFactory");
System.setProperty("Log4jLogEventFactory", "org.apache.logging.log4j.core.impl.DefaultLogEventFactory");
Configurator.initialize(null, configURL);
} catch (Exception ex ) {
System.err.println("Cannot initialize Log4J using configuration url:" + configURL);
}
}
}
凉!一切正常!!!和用法:
MyLoggerManager.initialize("Log4j2.xml");
MyLoggerInterface logger = MyLoggerInterface.getLogger(AppLauncher.class);
logger.info("test", MyLoggerAppenderEnum.Console);
但问题是,如果我使用扩展自定义记录器,我无法记录方法名称和行.布局是正确的!如果我不使用扩展自定义记录器,也会记录mehtod名称和行!
...
...
...
...
题:
我也想记录方法名称和行.但是我扩展我的记录器类后它不起作用(布局syntaxt是正确的!)
我找到了扩展记录器示例here
我的代码在gitlab这里
我使用log4j 2.9.1