Whee
Whee

Reputation: 269

Log4Net Logging Variables

Is it possible for log4net to log custom variables, or am I limited to the "pre-configured" variables? e.g.

  • %appdomain: the friendly name of the appdomain from which the log entry was made
  • %date: the local datetime when the log entry was made
  • %exception: a formatted form of the exception object in the log entry, if the entry contains an exception; otherwise, this format expression adds nothing to the log entry
  • etc

I need to log session information, from ActionExecutedContext for example. if that's relevant I call log4net from a Global Exception filter.

Is it possible, if so, how?

The currently configured appender, using only aforementioned "pre-configured" variables:

<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
      <bufferSize value="1" />
      <connectionType value="LALALA DELETED" />
      <commandText value="INSERT INTO Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      <parameter>
        <parameterName value="@log_date" />
        <dbType value="DateTime" />
        <layout type="log4net.Layout.RawTimeStampLayout" />
      </parameter>
      <parameter>
        <parameterName value="@thread" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%thread" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@log_level" />
        <dbType value="String" />
        <size value="50" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@logger" />
        <dbType value="String" />
        <size value="255" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@exception" />
        <dbType value="String" />
        <size value="2000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
    </appender>

Upvotes: 1

Views: 2044

Answers (1)

samy
samy

Reputation: 14962

In log4net a layout can contain many patterns, ie. classes that can output one specific information when encountering their string declaration in the layout.

For example %logger in the layout will resolve to the LoggerPatternConverter class, which outputs the logger name when encountered.

There is a global instantation of all the available patterns in the PatternLayout class:

PatternLayout.s_globalRulesRegistry = new Hashtable(45);
PatternLayout.s_globalRulesRegistry.Add("literal", typeof(LiteralPatternConverter));
PatternLayout.s_globalRulesRegistry.Add("newline", typeof(NewLinePatternConverter));
PatternLayout.s_globalRulesRegistry.Add("n", typeof(NewLinePatternConverter));
PatternLayout.s_globalRulesRegistry.Add("c", typeof(LoggerPatternConverter));

but you can add some custom patterns to your layout through the configuration. Just create your own pattern layout converter:

public class ZoinxPatternlayoutConverter: PatternLayoutConverter
{
    protected override void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        writer.Write("Zoinx at {0:d}", DateTime.Now);
    }
}

And add it to your layout:

<appender name="console" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern value="%message %zoinx %newline" />
    <converter>
      <name value="zoinx"/>
      <type value="App.ZoinxPatternLayoutConverter, App" />
    </converter>
  </layout>
</appender>

Of course in your case this may be a bit much and you would perhaps benefit from deriving from a Layout directly if you only ever use one property in each layout, such as the RawTimeStampLayout you have in your config. Alternatively you could inherit the PatternLayout to register all the patterns you're interested in once and for all and use them across your configuration.

Upvotes: 1

Related Questions