@@ -176,7 +176,6 @@ internal LogMsg Translate(LoggingEvent loggingEvent)
176176 StackifyError error = null ;
177177 object messageObject = null ;
178178 string errorAdditionalMessage = null ;
179-
180179 if ( loggingEvent . MessageObject != null && loggingEvent . MessageObject is StackifyError )
181180 {
182181 //Message Object was an exception
@@ -211,13 +210,35 @@ internal LogMsg Translate(LoggingEvent loggingEvent)
211210 // messageObject = loggingEvent.MessageObject;
212211 //}
213212 else
214- {
215- messageObject = loggingEvent . MessageObject ;
216- }
217-
218-
219- //messageObject is not an object we need to serialize.
220- if ( messageObject == null || messageObject is string || messageObject . GetType ( ) . FullName == "log4net.Util.SystemStringFormat" )
213+ {
214+ // we try to retrieve the thrown exception but wait to do this check until this last condition
215+ // block since we need to use reflection which is an expensive operation
216+ Exception thrownException = GetThrownException ( loggingEvent ) ;
217+
218+ if ( thrownException == null )
219+ {
220+ // the thrown exception does not exist, so we use the basic information provided in the message object
221+ messageObject = loggingEvent . MessageObject ;
222+ }
223+ else
224+ {
225+ if ( thrownException is StackifyError )
226+ {
227+ error = thrownException as StackifyError ;
228+ }
229+ else
230+ {
231+ error = StackifyError . New ( thrownException ) ;
232+ }
233+
234+ errorAdditionalMessage = loggingEvent . RenderedMessage ;
235+ messageObject = loggingEvent . MessageObject ;
236+ }
237+ }
238+
239+
240+ //messageObject is not an object we need to serialize.
241+ if ( messageObject == null || messageObject is string || messageObject . GetType ( ) . FullName == "log4net.Util.SystemStringFormat" )
221242 {
222243 //passing null to the serialize object since we can't serialize the logged object. We only need to get potential diags.
223244 msg . data = StackifyLib . Utils . HelperFunctions . SerializeDebugData ( null , false , diags ) ;
@@ -283,7 +304,23 @@ internal LogMsg Translate(LoggingEvent loggingEvent)
283304 return msg ;
284305 }
285306
286- private Dictionary < string , object > GetDiagnosticContextProperties ( )
307+ private Exception GetThrownException ( LoggingEvent loggingEvent )
308+ {
309+ // Since Sitecore's implementation does not expose the ExceptionObject, we need to use reflection to get access
310+ // to it, as per Matt Watson from Stackify. We know they store this Exception in a field with the name m_thrownException
311+ // so we retrieve the private field based on its name.
312+ Exception thrownException = null ;
313+ Type loggingEventType = loggingEvent . GetType ( ) ;
314+ var thrownExceptionFieldInfo = loggingEventType . GetField ( "m_thrownException" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic ) ;
315+ if ( thrownExceptionFieldInfo != null )
316+ {
317+ thrownException = thrownExceptionFieldInfo . GetValue ( loggingEvent ) as Exception ;
318+ }
319+
320+ return thrownException ;
321+ }
322+
323+ private Dictionary < string , object > GetDiagnosticContextProperties ( )
287324 {
288325 if ( ! _HasContextKeys )
289326 {
0 commit comments