Log4net one element FileAppender, programmatic access to multiple files

My web application supports multiple instances, for example. instance 1, 2, each of which writes data to its own file through log4net. That is, I want to programmatically write data to different files based on the instance ID. The path to the file should be:

D: \ Projects \ Log \ 1 \ Reporting.log, e.g. 1

D: \ Projects \ Log \ 2 \ Reporting.log e.g. 2

My web application supports 3 instances, do I need to have 3 C # registrars that ONLY differ in the path of the log file, as shown above?

Below is the Log4Net.config

<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> </configSections> <log4net> <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file value=????How to specify this????? /> <appendToFile value="true" /> <rollingStyle value="Date" /> <datePattern value="-yyyy-MM-dd.lo\g" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <param name="Header" value="------------------------------------------&#13;&#10;" /> <param name="Footer" value="------------------------------------------&#13;&#10;" /> <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/> </layout> </appender> <!-- Setup the root category, add the appenders and set the default level --> <root> <level value="ERROR" /> <appender-ref ref="ExceptionLogFileAppender" /> </root> </log4net> </configuration> 

UPDATE

Instance ID must be 1.2, etc.

The instance ID will have more than 100 in the future.

Any idea would be greatly appreciated!

+4
source share
4 answers

Well, I can't think of a way to register each instance (1, 2, 3), but you can easily register them by PID. I would change the <file> element to:

 <file type="log4net.Util.PatternString"> <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" /> </file> 

Then remove the element that should give:

  <appender name="ExceptionLogFileAppender" type="log4net.Appender.RollingFileAppender"> <file type="log4net.Util.PatternString"> <conversionPattern value="log\%processid\yourFileName.%date{yyyyMMMdd}.log" /> </file> <appendToFile value="true" /> <rollingStyle value="Date" /> <param name="StaticLogFileName" value="false" /> <layout type="log4net.Layout.PatternLayout"> <param name="Header" value="------------------------------------------&#13;&#10;" /> <param name="Footer" value="------------------------------------------&#13;&#10;" /> <conversionPattern value="%d|[%t]|%-5p|%c|%m%n"/> </layout> </appender> 

Then each instance must be registered in accordance with it PID:

 c:\log\13242\yourFileName.20111025.log 

Or you can do the pid part of the file name instead of another directory that I would recommend, so you do not put the c: \ log \ folder in several directories:

 <file type="log4net.Util.PatternString"> <conversionPattern value="log\yourFileName.%processid.%date{yyyyMMMdd}.log" /> </file> 

This will give you files like:

 c:\log\yourFileName.13142.20111025.log c:\log\yourFileName.13152.20111025.log 
+2
source

See this example . Basically, if the number of instances is manageable and finite, you can create a log application for each of them. Then you add a filter to each of them and set the StringToMatch property for each of them to an instance identifier.

Please note that this is not entirely dynamic, because you will need to specify each of these additives ahead of time.

+2
source

This should work, this is a bit of work, and it is based on the answer to the kit here .

Before calling XmlConfigurator.Configure(); add

 ConverterRegistry.AddConverter(typeof(InstancePatternString), typeof(InstancePatternStringConverter)); 

Then add the following classes to your solution:

 public class InstancePatternString : PatternString { public InstancePatternString(string pattern): base(pattern) { } public override void ActivateOptions() { AddConverter("cs", typeof(InstancePatternConverter)); base.ActivateOptions(); } } public class InstancePatternConverter : PatternConverter { override protected void Convert(TextWriter writer, object state) { switch(Option) { case "instance": writer.Write(MyContext.Instance); break; } } } public class InstancePatternStringConverter : IConvertTo, IConvertFrom { public bool CanConvertFrom(Type sourceType) { return sourceType == typeof(string); } public bool CanConvertTo(Type targetType) { return typeof(string).IsAssignableFrom(targetType); } public object ConvertFrom(object source) { var pattern = source as string; if (pattern == null) throw ConversionNotSupportedException.Create(typeof(InstancePatternString), source); return new InstancePatternString(pattern); } public object ConvertTo(object source, Type targetType) { var pattern = source as PatternString; if (pattern == null || !CanConvertTo(targetType)) throw ConversionNotSupportedException.Create(targetType, source); return pattern.Format(); } } 

Be sure to change MyContext.Instance to a statically accessible property that represents your instance.

Finally, change your web.config:

 <file value=????How to specify this????? /> 

in

 <file type="ConsoleApp.InstancePatternString, ConsoleApp" value="%cs{instance}\Reporting.log" /> 

Where ConsoleApp is the assembly in which you added these classes. This will create log files in separate instance directories. i.e. 1 \ Reporting.log, 2 \ Reporting.log, etc.

The advantage of this approach is that adding future properties is quite simple and just requires adding a switch statement to use in any future log / location file names.

+1
source

Not exactly the solution for the file system log, but what about entering the database table and including the instance detail? This will simplify the differentiation of instance-specific messages, and almost zero maintenance and high scalability.

0
source

All Articles