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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With