问题描述
我正在尝试在log4j2中编码自己的rewritePolicy. documentation
RewritePolicy是一个允许实现检查的接口 并可能在将其传递给Appender之前修改. RewritePolicy声明了一种名为重写的方法,必须是 实施的.该方法通过了le孔,可以返回相同的 事件或创建一个新的.
这是我的 Java类:
public final class MarkerInjectorRewritePolicy implements RewritePolicy { @Override public LogEvent rewrite(final LogEvent event) { final Marker marker = event.getMarker(); if (marker == null) return event; // If there's a Marker, add it to the ThreadContextMap so the RoutingAppender can properly routes log messages event.getContextMap().put("_marker", marker.getName()); return event; } }
这是我的 yaml配置文件:
Rewrite: name: REWRITE_APPENDER AppenderRef: ref: ROUTING_APPENDER PropertiesRewritePolicy: Property: - name: foo value: bar
但是,我不知道如何将其注入我的配置文件中.我如何在运行时工作?
推荐答案
您的自定义重写策略应编码为log4j2插件.这使您能够在重写pppender中配置自定义rewritePolicy.
@Plugin(name = "InjectMarkerPolicy", category = "Core", elementType = "rewritePolicy", printObject = true) public final class MarkerInjectorRewritePolicy implements RewritePolicy { @Override public LogEvent rewrite(final LogEvent event) { final Marker marker = event.getMarker(); if (marker == null) return event; // If there's a Marker, add it to the ThreadContextMap // so the RoutingAppender can properly routes log messages // event's context map is immutable, so need to make a copy... Map<String, String> mdc = new HashMap<>(event.getContextMap()); mdc.put("_marker", marker.getName()); LogEvent result = new Log4jLogEvent(event.getLoggerName(), event.getMarker(), event.getLoggerFqcn(), event.getLevel(), event.getMessage(), event.getThrown(), mdc, event.getContextStack(), event.getThreadName(), event.getSource(), event.getTimeMillis()); return result; } }
示例config(todo:设置包装属性的正确值):
<Configuration status="trace" packages="my.rewritepolicy.plugin.package"> <Appenders> <Console name="STDOUT"> <PatternLayout pattern="[%-5level] %c{1.} %m%n"/> </Console> <Rewrite name="Rewrite"> <InjectMarkerPolicy /> <AppenderRef ref="STDOUT"/> </Rewrite> </Appenders> <Loggers> <Root level="trace"> <AppenderRef ref="Rewrite"/> </Root> </Loggers> </Configuration>
其他推荐答案
不要忘记插件的工厂方法,否则它将无法启动:
@PluginFactory public static MarkerInjectorRewritePolicy createPolicy() { return new MarkerInjectorRewritePolicy(); }
这是我的github帐户上的一个工作示例: RewriteAppender/
问题描述
I'm trying to code my own RewritePolicy in Log4j2. The documentation states that :
RewritePolicy is an interface that allows implementations to inspect and possibly modify LogEvents before they are passed to Appender. RewritePolicy declares a single method named rewrite that must be implemented. The method is passed the LogEvent and can return the same event or create a new one.
Here's my java class :
public final class MarkerInjectorRewritePolicy implements RewritePolicy { @Override public LogEvent rewrite(final LogEvent event) { final Marker marker = event.getMarker(); if (marker == null) return event; // If there's a Marker, add it to the ThreadContextMap so the RoutingAppender can properly routes log messages event.getContextMap().put("_marker", marker.getName()); return event; } }
Here's my yaml configuration file :
Rewrite: name: REWRITE_APPENDER AppenderRef: ref: ROUTING_APPENDER PropertiesRewritePolicy: Property: - name: foo value: bar
However I have no idea how to inject it in my configuration file. How can I make it work at runtime?
推荐答案
Your custom rewrite policy should be coded as a log4j2 plugin. This enables you to configure your custom RewritePolicy in a RewriteAppender.
@Plugin(name = "InjectMarkerPolicy", category = "Core", elementType = "rewritePolicy", printObject = true) public final class MarkerInjectorRewritePolicy implements RewritePolicy { @Override public LogEvent rewrite(final LogEvent event) { final Marker marker = event.getMarker(); if (marker == null) return event; // If there's a Marker, add it to the ThreadContextMap // so the RoutingAppender can properly routes log messages // event's context map is immutable, so need to make a copy... Map<String, String> mdc = new HashMap<>(event.getContextMap()); mdc.put("_marker", marker.getName()); LogEvent result = new Log4jLogEvent(event.getLoggerName(), event.getMarker(), event.getLoggerFqcn(), event.getLevel(), event.getMessage(), event.getThrown(), mdc, event.getContextStack(), event.getThreadName(), event.getSource(), event.getTimeMillis()); return result; } }
Example config (TODO: set correct value for packages attribute):
<Configuration status="trace" packages="my.rewritepolicy.plugin.package"> <Appenders> <Console name="STDOUT"> <PatternLayout pattern="[%-5level] %c{1.} %m%n"/> </Console> <Rewrite name="Rewrite"> <InjectMarkerPolicy /> <AppenderRef ref="STDOUT"/> </Rewrite> </Appenders> <Loggers> <Root level="trace"> <AppenderRef ref="Rewrite"/> </Root> </Loggers> </Configuration>
其他推荐答案
Don't forget the Factory Method for your plugin or it will fail to start:
@PluginFactory public static MarkerInjectorRewritePolicy createPolicy() { return new MarkerInjectorRewritePolicy(); }
here's a working example on my github account: https://github.com/sercasti/Log4j-RewriteAppender/