Question

I am trying to log exceptions into a database with Log4Net. I am using the adonetappender and it does work, but not optimally.

If I configure the exception parameter like this...

<parameter>
  <parameterName value="@exception"/>
  <dbType value="String"/>
  <size value="-1"/>
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%exception"/>
  </layout>
</parameter>

It works but inserts "" instead of null when there is no exception.

I get the same result if I have it like this...

<parameter>
  <parameterName value="@exception"/>
  <dbType value="String"/>
  <size value="-1"/>
  <layout type="log4net.Layout.ExceptionLayout">
    <!-- <key value="exception" /> -->
    <!--<conversionPattern value="%exception"/>-->
  </layout>
</parameter>

But if I have it like this

<parameter>
  <parameterName value="@exception"/>
  <dbType value="String"/>
  <size value="-1"/>
  <layout type="log4net.Layout.RawPropertyLayout">
    <key value="exception" />
  </layout>
</parameter>

It only inserts null values ...

The problem might be coming from that we have a static logging wrapper that always calls

LogManager.GetLogger("[GoodLife.Common.Logging]").Debug(message, e); // e being null if there is no exception. 

Is there a way for me to have it insert nulls if e is null when I call the debug method on the logger?

The log4net documentation on the layouts isn't all that helpful and I got the last configuration from Default values for AdoNetAppender parameter

Was it helpful?

Solution

The problem is that the exception is not a property and therefore log4net cannot find anything with the key "exception" and thus you get always null.

In order to solve your problem you can create your own layout converter like this:

public class RawExceptionLayout : IRawLayout
{       
    public virtual object Format(LoggingEvent loggingEvent)
    {
         return loggingEvent.ExceptionObject;
    }       
}

OTHER TIPS

You can also modify the used insert statement by log4net and let sql server do the work for you. This has the benefit of not requiring code changes!

Default sample config:

 <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) 
 VALUES (@log_date, @thread, @log_level, @logger, @message, 
@exception)" />

and my modified insert:

 <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) 
 VALUES (@log_date, @thread, @log_level, @logger, @message, 
case when  @exception &lt;&gt; '' then @exception else null end)" />

notice the required encoding of < and > because it is in xml!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top