Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Additional Stacktrace info when serializing log4net properties to Json

I'm attempting to serialize my logs to Json. I'm using log4net with a custom layout, but when an exception is logged, I get the following malformed JSON (Note the additional stacktrace info at the end)

Am I missing a setting for log4net, or is this a serialization issue?

UPDATE: This has to be something with log4net, because json.net serializes an Exception perfectly.

***UPDATE (FIXED): Updated code below.

{
    "UserSessionId":"4b146c92-fe99-4f78-bbef-720df2cf7473",
    "ProcessSessionId":1,
    ...
    "Logger":"testharness.Program","ThreadName":"1",
    "ExceptionObject":{
        "ClassName":"System.ApplicationException",
        "Message":"Test Exception Logging",
        "Data":null,
        "InnerException":null,
        "HelpURL":null,
        "StackTraceString":"   at testharness.Program.Main(String[] args) in C:\\temp\\testharness\\Program.cs:line 18",
        "RemoteStackTraceString":null,
        ...
        "WatsonBuckets":null
    },
    ...
        "log4net:HostName":"ol-4RBNMH2"
    }}
System.ApplicationException: Test Exception Logging
   at testharness.Program.Main(String[] args) in C:\temp\testharness\Program.cs:line 18

log4net configuratiton

<log4net>
    <appender name="RollingFileCompositeAppender" type="log4net.Appender.RollingFileAppender">
      <file value="c:\\logs\\testharness.txt"/>
      <appendToFile value="true"/>

      <rollingStyle value="Composite"/>
      <datePattern value="yyyy-MM-dd"/>
      <maxSizeRollBackups value="-1"/>
      <maximumFileSize value="1MB"/>
      <countDirection value="1"/>
      <preserveLogFileNameExtension value="false"/>
      <staticLogFileName value="false"/>
      <layout type="Company.log4net.JsonLayout"></layout>
    </appender>

    <root>
      <level value="ALL"/>
      <appender-ref ref="RollingFileCompositeAppender"/>
    </root>
  </log4net>

The Custom Layout class

    public class JsonLayout : LayoutSkeleton
    {
        public JsonLayout() {
            IgnoresException = false;
        }
...
        /// <inheritdoc />
        public override void ActivateOptions()
        {
        }

        /// <inheritdoc />
        public override void Format(TextWriter writer, LoggingEvent loggingEvent)
        {
            _customProperties.PhysicalMemory = Process.GetCurrentProcess().WorkingSet64;
            var evt = new CustomLoggingEvent(loggingEvent, _customProperties);
            writer.Write(JsonConvert.SerializeObject(evt));
        }
    }


    [JsonObject(MemberSerialization.OptIn)]
    public class CustomLoggingEvent
    {

 ... 

        [JsonProperty]
        public Exception ExceptionObject { get; set; }
        [JsonProperty]
        public long PhysicalMemory { get; set; }
        [JsonProperty]
        public PropertiesDictionary Properties { get; set; }
    }

The Test Harness:

   internal class Program
    {
        private static void Main()
        {
            Console.WriteLine($"{typeof(JsonLayout)}");
            var log = log4net.LogManager.GetLogger(typeof(Program));
            try
            {
                log.Debug("hello again world");
                throw new ApplicationException("Test Exception Logging");
            }
            catch (Exception e)
            {
                log.Error("Exception Thrown", e);
            }

            Console.ReadLine();

        }
    }
like image 865
Eric Smith Avatar asked Feb 03 '26 07:02

Eric Smith


1 Answers

I downloaded the log4net source and found the issue. When creating a custom layout implementing LayoutSkeleton, if your layout handles the LoggingEvent.ExceptionObject, then the IgnoresException property should be set to false; the default value is true. I updated the code in the question with a constructor wherein the IgnoresException property is set to true. I probably should have waited a day while I researched, but maybe this will help someone else.

like image 104
Eric Smith Avatar answered Feb 06 '26 04:02

Eric Smith



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!