Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

log4net GlobalContext.Properties set only once

Tags:

c#

log4net

I would like to extend my log file with static information, like what OS my software is running.

Is there a way to inject this information only once per file that was created and not for every log entry?

This is how I am doing it currently (but this results in outputting the information over and over again - which isnt necessary since it static information)

GlobalContext.Properties["**evInfoOsPlatform**"] = string.Format("OS Platform: {0}", Environment.OSVersion.Platform);

<layout type="log4net.Layout.PatternLayout">
  <conversionPattern value="%date{ABSOLUTE} [%thread] %level 
                        %logger - %message%newlineOperating System Version: %property{
                        **evInfoOsPlatform**}%newline%exception"/>
</layout>

My desired effect would be a logfile looking like this:

Static information:
OS Version: Windows 8.1.0101934 32-bit
Culture Info: en-US
Domainname: RandomDomain
Username: Emil
Userrights: Admin      

Messages:
//now all the messages should be printed...

This code is used in a C# .Net 4.5 WPF environment.

Hope you can help.

like image 614
Rand Random Avatar asked Oct 16 '13 09:10

Rand Random


People also ask

What is the use of context properties in log4net?

Context Properties The log4net contexts store properties, i.e. name value pairs. The name is a string the value is any object. A property can be set as follows: log4net.

What are log4net Appenders?

For log4net to know where to store your log messages, you add one or more appenders to your configuration. An appender is a C# class that can transform a log message, including its properties, and persist it somewhere. Examples of appenders are the console, a file, a database, an API call, elmah.io, etc.

What is log4net config?

The log4net configuration can be configured using assembly-level attributes rather than specified programmatically. If specified, this is the filename of the configuration file to use with the XmlConfigurator. This file path is relative to the application base directory (AppDomain. CurrentDomain.


1 Answers

If you're using a RollingFileAppender, take a look at this question - essentially you want to create a class that inherits from RollingFileAppender and override the WriteHeader method to only write the header once to each file.

This answer shows the best way to set the Header property, by subclassing log4net.Layout.PatternLayout

Putting those together in an example:

namespace MyAssembly.log4net.Header.Example
{
    public class HeaderAppender : RollingFileAppender
    {
        protected override void WriteHeader()
        {
            if (LockingModel.AcquireLock().Length == 0)
            {
                base.WriteHeader();
            }
        }
    }

    public class HeaderPatternLayout : PatternLayout
    {
        public override string Header
        {
            get
            {
                StringBuilder headerBuilder = new StringBuilder();
                headerBuilder.AppendLine("Static information");
                headerBuilder.AppendLine("OS Version: "
                          + Environment.OSVersion);
                headerBuilder.AppendLine("Culture Info: "
                          + CultureInfo.CurrentCulture);
                headerBuilder.AppendLine("[Etc] ");
                headerBuilder.AppendLine();
                headerBuilder.AppendLine("Messages:");    

                return headerBuilder.ToString();
            }
        }
    }
}

Given config like this (you would need to set the assembly names to the correct ones):

<configuration>
  <configSections>
    <section name="log4net"
        type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>

  <log4net debug="false">

    <appender name="HeaderAppender" 
              type="MyAssembly.log4net.Header.Example.HeaderAppender,MyAssembly">
      <file value="c:\temp\Test.log"/>
      <layout 
         type="MyAssembly.log4net.Header.Example.HeaderPatternLayout,MyAssembly">
        <conversionPattern value="%message%newline" />
      </layout>
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
      <maximumFileSize value="5MB"/>
      <rollingStyle value="Size"/>
      <maxSizeRollBackups value="-1"/>
      <countDirection value="1"/>
    </appender>

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

  </log4net>

</configuration>

Then this is the resulting log file, complete with header:

Static information
OS Version: Microsoft Windows NT 6.1.7601 Service Pack 1
Culture Info: en-GB
[Etc] 

Messages:
Info Message
Debug Message
Etc 
like image 196
stuartd Avatar answered Oct 13 '22 13:10

stuartd