8383import com .google .gson .Gson ;
8484import com .splunk .logging .hec .MetadataTags ;
8585
86- import java .util .HashMap ;
87- import java .util .LinkedHashMap ;
88- import java .util .Locale ;
89- import java .util .Map ;
90- import java .util .logging .Handler ;
91- import java .util .logging .LogManager ;
92- import java .util .logging .LogRecord ;
86+ import java .util .*;
87+ import java .util .logging .*;
9388
9489/**
9590 * An input handler for Splunk http event collector. This handler can be used by
9893 */
9994public final class HttpEventCollectorLoggingHandler extends Handler {
10095 private HttpEventCollectorSender sender = null ;
101- private final String IncludeLoggerNameConfTag = "include_logger_name" ;
96+ private final String includeLoggerNameConfTag = "include_logger_name" ;
10297 private final boolean includeLoggerName ;
103- private final String IncludeThreadNameConfTag = "include_thread_name" ;
98+ private final String includeThreadNameConfTag = "include_thread_name" ;
10499 private final boolean includeThreadName ;
105- private final String IncludeExceptionConfTag = "include_exception" ;
106- private final boolean includeException ;
100+ private final String includeExceptionConfTag = "include_exception" ;
101+ private boolean includeException ;
107102
108103
109- private final String BatchDelayConfTag = "batch_interval" ;
110- private final String BatchCountConfTag = "batch_size_count" ;
111- private final String BatchSizeConfTag = "batch_size_bytes" ;
112- private final String RetriesOnErrorTag = "retries_on_error" ;
113- private final String UrlConfTag = "url" ;
114- private final String SendModeTag = "send_mode" ;
115- private final String MiddlewareTag = "middleware" ;
104+ private final String batchDelayConfTag = "batch_interval" ;
105+ private final String batchCountConfTag = "batch_size_count" ;
106+ private final String batchSizeConfTag = "batch_size_bytes" ;
107+ private final String retriesOnErrorTag = "retries_on_error" ;
108+ private final String urlConfTag = "url" ;
109+ private final String sendModeTag = "send_mode" ;
110+ private final String middlewareTag = "middleware" ;
116111
117- private final String ConnectTimeoutConfTag = "connect_timeout" ;
118- private final String CallTimeoutConfTag = "call_timeout" ;
119- private final String ReadTimeoutConfTag = "read_timeout" ;
120- private final String WriteTimeoutConfTag = "write_timeout" ;
121- private final String TerminationTimeoutConfTag = "termination_timeout" ;
112+ private final String connectTimeoutConfTag = "connect_timeout" ;
113+ private final String callTimeoutConfTag = "call_timeout" ;
114+ private final String readTimeoutConfTag = "read_timeout" ;
115+ private final String writeTimeoutConfTag = "write_timeout" ;
116+ private final String terminationTimeoutConfTag = "termination_timeout" ;
122117
123118 /** HttpEventCollectorLoggingHandler c-or */
124119 public HttpEventCollectorLoggingHandler () {
@@ -141,7 +136,7 @@ public HttpEventCollectorLoggingHandler() {
141136 getConfigurationProperty (MetadataTags .MESSAGEFORMAT , null ));
142137
143138 // http event collector endpoint properties
144- String url = getConfigurationProperty (UrlConfTag , null );
139+ String url = getConfigurationProperty (urlConfTag , null );
145140
146141 // app token
147142 String token = getConfigurationProperty ("token" , null );
@@ -153,26 +148,26 @@ public HttpEventCollectorLoggingHandler() {
153148 String type = getConfigurationProperty ("type" , null );
154149
155150 // batching properties
156- long delay = getConfigurationNumericProperty (BatchDelayConfTag , HttpEventCollectorSender .DefaultBatchInterval );
157- long batchCount = getConfigurationNumericProperty (BatchCountConfTag , HttpEventCollectorSender .DefaultBatchCount );
158- long batchSize = getConfigurationNumericProperty (BatchSizeConfTag , HttpEventCollectorSender .DefaultBatchSize );
159- long retriesOnError = getConfigurationNumericProperty (RetriesOnErrorTag , 0 );
160- String sendMode = getConfigurationProperty (SendModeTag , "sequential" );
151+ long delay = getConfigurationNumericProperty (batchDelayConfTag , HttpEventCollectorSender .DefaultBatchInterval );
152+ long batchCount = getConfigurationNumericProperty (batchCountConfTag , HttpEventCollectorSender .DefaultBatchCount );
153+ long batchSize = getConfigurationNumericProperty (batchSizeConfTag , HttpEventCollectorSender .DefaultBatchSize );
154+ long retriesOnError = getConfigurationNumericProperty (retriesOnErrorTag , 0 );
155+ String sendMode = getConfigurationProperty (sendModeTag , "sequential" );
161156 String eventHeaderSerializer = getConfigurationProperty ("eventHeaderSerializer" , "" );
162- String middleware = getConfigurationProperty (MiddlewareTag , null );
157+ String middleware = getConfigurationProperty (middlewareTag , null );
163158 String eventBodySerializer = getConfigurationProperty ("eventBodySerializer" , null );
164159 String errorCallbackClass = getConfigurationProperty ("errorCallback" , null );
165160
166- includeLoggerName = getConfigurationBooleanProperty (IncludeLoggerNameConfTag , true );
167- includeThreadName = getConfigurationBooleanProperty (IncludeThreadNameConfTag , true );
168- includeException = getConfigurationBooleanProperty (IncludeExceptionConfTag , true );
161+ includeLoggerName = getConfigurationBooleanProperty (includeLoggerNameConfTag , true );
162+ includeThreadName = getConfigurationBooleanProperty (includeThreadNameConfTag , true );
163+ includeException = getConfigurationBooleanProperty (includeExceptionConfTag , true );
169164
170165 HttpEventCollectorSender .TimeoutSettings timeoutSettings = new HttpEventCollectorSender .TimeoutSettings (
171- getConfigurationNumericProperty (ConnectTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_CONNECT_TIMEOUT ),
172- getConfigurationNumericProperty (CallTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_CALL_TIMEOUT ),
173- getConfigurationNumericProperty (ReadTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_READ_TIMEOUT ),
174- getConfigurationNumericProperty (WriteTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_WRITE_TIMEOUT ),
175- getConfigurationNumericProperty (TerminationTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_TERMINATION_TIMEOUT )
166+ getConfigurationNumericProperty (connectTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_CONNECT_TIMEOUT ),
167+ getConfigurationNumericProperty (callTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_CALL_TIMEOUT ),
168+ getConfigurationNumericProperty (readTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_READ_TIMEOUT ),
169+ getConfigurationNumericProperty (writeTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_WRITE_TIMEOUT ),
170+ getConfigurationNumericProperty (terminationTimeoutConfTag , HttpEventCollectorSender .TimeoutSettings .DEFAULT_TERMINATION_TIMEOUT )
176171 );
177172
178173 if ("raw" .equalsIgnoreCase (type )) {
@@ -240,9 +235,15 @@ public HttpEventCollectorLoggingHandler() {
240235 @ Override
241236 public void publish (LogRecord record ) {
242237
243- // Exception thrown in application is wrapped with relevant information instead of just a message.
244- Map <Object , Object > exceptionDetailMap = new LinkedHashMap <>();
245- if (record .getThrown () != null ) {
238+ boolean isExceptionOccured = false ;
239+ String exceptionDetail = null ;
240+ /*
241+ Exception details are only populated when any SEVERE error occurred & exception is actually thrown
242+ */
243+ if (Level .SEVERE .equals (record .getLevel ()) && record .getThrown () != null ) {
244+
245+ // Exception thrown in application is wrapped with relevant information instead of just a message.
246+ Map <Object , Object > exceptionDetailMap = new LinkedHashMap <>();
246247 StackTraceElement [] elements = record .getThrown ().getStackTrace ();
247248 exceptionDetailMap .put ("detailMessage" , record .getThrown ().getMessage ());
248249 exceptionDetailMap .put ("exceptionClass" , record .getThrown ().getClass ().toString ());
@@ -253,6 +254,8 @@ public void publish(LogRecord record) {
253254 exceptionDetailMap .put ("lineNumber" , String .valueOf (elements [0 ].getLineNumber ()));
254255 exceptionDetailMap .put ("methodName" , elements [0 ].getMethodName ());
255256 }
257+ exceptionDetail = new Gson ().toJson (exceptionDetailMap );
258+ isExceptionOccured = true ;
256259 }
257260
258261 this .sender .send (
@@ -262,7 +265,7 @@ public void publish(LogRecord record) {
262265 includeLoggerName ? record .getLoggerName () : null ,
263266 includeThreadName ? String .format (Locale .US , "%d" , record .getThreadID ()) : null ,
264267 null , // no property map available
265- (! includeException || record . getThrown () == null ) ? null : new Gson (). toJson ( exceptionDetailMap ) ,
268+ (includeException && isExceptionOccured ) ? exceptionDetail : null ,
266269 null // no marker available
267270 );
268271 }
0 commit comments