6

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.

4

1 回答 1

3

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 
于 2013-11-23T17:42:51.487 回答