2121import java .util .Map ;
2222import java .util .concurrent .TimeUnit ;
2323
24- import com .splunk .logging .hec .MetadataTags ;
25- import org .apache .logging .log4j .core .appender .AbstractAppender ;
2624import org .apache .logging .log4j .core .Filter ;
2725import org .apache .logging .log4j .core .Layout ;
28- import org .apache .logging .log4j .core .config .Property ;
29- import org .apache .logging .log4j .core .layout .PatternLayout ;
3026import org .apache .logging .log4j .core .LogEvent ;
27+ import org .apache .logging .log4j .core .appender .AbstractAppender ;
28+ import org .apache .logging .log4j .core .config .Node ;
29+ import org .apache .logging .log4j .core .config .Property ;
3130import org .apache .logging .log4j .core .config .plugins .Plugin ;
3231import org .apache .logging .log4j .core .config .plugins .PluginAttribute ;
3332import org .apache .logging .log4j .core .config .plugins .PluginElement ;
3433import org .apache .logging .log4j .core .config .plugins .PluginFactory ;
34+ import org .apache .logging .log4j .core .config .plugins .PluginNode ;
35+ import org .apache .logging .log4j .core .config .plugins .util .PluginType ;
36+ import org .apache .logging .log4j .core .layout .PatternLayout ;
37+
38+ import com .splunk .logging .HttpEventCollectorMiddleware .HttpSenderMiddleware ;
39+ import com .splunk .logging .hec .MetadataTags ;
3540
3641/**
3742 * Splunk Http Appender.
4045@ SuppressWarnings ("serial" )
4146public final class HttpEventCollectorLog4jAppender extends AbstractAppender
4247{
48+ public static final String BODY_SERIALIZER_TYPE = "eventBodySerializer" ;
49+ public static final String HEADER_SERIALIZER_TYPE = "eventHeaderSerializer" ;
50+ public static final String MIDDLEWARE_TYPE = "middleware" ;
51+
4352 private HttpEventCollectorSender sender = null ;
4453 private final boolean includeLoggerName ;
4554 private final boolean includeThreadName ;
@@ -70,10 +79,10 @@ private HttpEventCollectorLog4jAppender(final String name,
7079 long batchSize ,
7180 long retriesOnError ,
7281 String sendMode ,
73- String middleware ,
82+ final HttpSenderMiddleware middleware ,
7483 final String disableCertificateValidation ,
75- final String eventBodySerializer ,
76- final String eventHeaderSerializer ,
84+ final EventBodySerializer eventBodySerializer ,
85+ final EventHeaderSerializer eventHeaderSerializer ,
7786 HttpEventCollectorSender .TimeoutSettings timeoutSettings )
7887 {
7988 super (name , filter , layout , ignoreExceptions , Property .EMPTY_ARRAY );
@@ -87,22 +96,16 @@ private HttpEventCollectorLog4jAppender(final String name,
8796 this .sender = new HttpEventCollectorSender (url , token , channel , type , batchInterval , batchCount , batchSize , sendMode , metadata , timeoutSettings );
8897
8998 // plug a user middleware
90- if (middleware != null && !middleware .isEmpty ()) {
91- try {
92- this .sender .addMiddleware ((HttpEventCollectorMiddleware .HttpSenderMiddleware )(Class .forName (middleware ).newInstance ()));
93- } catch (Exception ignored ) {}
99+ if (middleware != null ) {
100+ this .sender .addMiddleware (middleware );
94101 }
95102
96- if (eventBodySerializer != null && !eventBodySerializer .isEmpty ()) {
97- try {
98- this .sender .setEventBodySerializer ((EventBodySerializer ) Class .forName (eventBodySerializer ).newInstance ());
99- } catch (final Exception ignored ) {}
103+ if (eventBodySerializer != null ) {
104+ this .sender .setEventBodySerializer (eventBodySerializer );
100105 }
101106
102- if (eventHeaderSerializer != null && !eventHeaderSerializer .isEmpty ()) {
103- try {
104- this .sender .setEventHeaderSerializer ((EventHeaderSerializer ) Class .forName (eventHeaderSerializer ).newInstance ());
105- } catch (final Exception ignored ) {}
107+ if (eventHeaderSerializer != null ) {
108+ this .sender .setEventHeaderSerializer (eventHeaderSerializer );
106109 }
107110
108111 // plug resend middleware
@@ -144,10 +147,10 @@ public static HttpEventCollectorLog4jAppender createAppender(
144147 @ PluginAttribute ("batch_interval" ) final String batchInterval ,
145148 @ PluginAttribute ("retries_on_error" ) final String retriesOnError ,
146149 @ PluginAttribute ("send_mode" ) final String sendMode ,
147- @ PluginAttribute ("middleware" ) final String middleware ,
150+ @ PluginAttribute (MIDDLEWARE_TYPE ) final String middlewareClassName ,
148151 @ PluginAttribute ("disableCertificateValidation" ) final String disableCertificateValidation ,
149- @ PluginAttribute ("eventBodySerializer" ) final String eventBodySerializer ,
150- @ PluginAttribute ("eventHeaderSerializer" ) final String eventHeaderSerializer ,
152+ @ PluginAttribute (BODY_SERIALIZER_TYPE ) final String eventBodySerializerClassName ,
153+ @ PluginAttribute (HEADER_SERIALIZER_TYPE ) final String eventHeaderSerializerClassName ,
151154 @ PluginAttribute (value = "includeLoggerName" , defaultBoolean = true ) final boolean includeLoggerName ,
152155 @ PluginAttribute (value = "includeThreadName" , defaultBoolean = true ) final boolean includeThreadName ,
153156 @ PluginAttribute (value = "includeMDC" , defaultBoolean = true ) final boolean includeMDC ,
@@ -158,7 +161,8 @@ public static HttpEventCollectorLog4jAppender createAppender(
158161 @ PluginAttribute (value = "read_timeout" , defaultLong = HttpEventCollectorSender .TimeoutSettings .DEFAULT_READ_TIMEOUT ) final long readTimeout ,
159162 @ PluginAttribute (value = "write_timeout" , defaultLong = HttpEventCollectorSender .TimeoutSettings .DEFAULT_WRITE_TIMEOUT ) final long writeTimeout ,
160163 @ PluginElement ("Layout" ) Layout <? extends Serializable > layout ,
161- @ PluginElement ("Filter" ) final Filter filter
164+ @ PluginElement ("Filter" ) final Filter filter ,
165+ @ PluginNode final Node node
162166 )
163167 {
164168 // The raw endpoint presumes that a single post is a single event.
@@ -202,6 +206,52 @@ public static HttpEventCollectorLog4jAppender createAppender(
202206 .build ();
203207 }
204208
209+ // Retrieve the additional elements through Log4j plugin mechanism first
210+ HttpSenderMiddleware middleware = null ;
211+ EventBodySerializer eventBodySerializer = null ;
212+ EventHeaderSerializer eventHeaderSerializer = null ;
213+ for (final Node child : node .getChildren ()) {
214+ final PluginType < ? > pluginType = child .getType ();
215+ final Object component = child .getObject ();
216+ switch (pluginType .getElementName ()) {
217+ case MIDDLEWARE_TYPE :
218+ middleware = (HttpSenderMiddleware ) component ;
219+ break ;
220+ case BODY_SERIALIZER_TYPE :
221+ eventBodySerializer = (EventBodySerializer ) component ;
222+ break ;
223+ case HEADER_SERIALIZER_TYPE :
224+ eventHeaderSerializer = (EventHeaderSerializer ) component ;
225+ break ;
226+ default :
227+ }
228+ }
229+
230+ // Fallback on instantiating classes
231+ if (middlewareClassName != null && !middlewareClassName .isEmpty ()) {
232+ try {
233+ middleware = (HttpSenderMiddleware ) Class .forName (middlewareClassName ).newInstance ();
234+ } catch (Exception e ) {
235+ LOGGER .warn ("The middleware {} could not be instantiated." , middlewareClassName , e );
236+ }
237+ }
238+
239+ if (eventBodySerializerClassName != null && !eventBodySerializerClassName .isEmpty ()) {
240+ try {
241+ eventBodySerializer = (EventBodySerializer ) Class .forName (eventBodySerializerClassName ).newInstance ();
242+ } catch (final Exception e ) {
243+ LOGGER .warn ("The event body serializer {} could not be instantiated." , eventBodySerializerClassName , e );
244+ }
245+ }
246+
247+ if (eventHeaderSerializerClassName != null && !eventHeaderSerializerClassName .isEmpty ()) {
248+ try {
249+ eventHeaderSerializer = (EventHeaderSerializer ) Class .forName (eventHeaderSerializerClassName ).newInstance ();
250+ } catch (final Exception e ) {
251+ LOGGER .warn ("The event header serializer {} could not be instantiated." , eventHeaderSerializerClassName , e );
252+ }
253+ }
254+
205255 final boolean ignoreExceptionsBool = Boolean .getBoolean (ignoreExceptions );
206256
207257 return new HttpEventCollectorLog4jAppender (
0 commit comments