I am currently running a windows service that creates multiple instances of a class.
At the top of the service class and every other class in my solution, I have something like this:
private static readonly ILog _log = LogManager.GetLogger(typeof(SomeClassTypeHere));
In my App.config, I have Log4Net configured for a single file:
<log4net debug="true">
<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
<file value="Logs\SomeLogFileName.xml" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<countDirection value="1" />
<maxSizeRollBackups value="30" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.XmlLayoutSchemaLog4j">
<locationInfo value="true" />
</layout>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
This works great in most respects, and everything logs to a single file. However, I'd really like to create a separate log file for each instance of a particular class that my service creates.
This is a class that we often need to monitor for support and we can have a handful of instances running at the same time.
We don't know which instances will be running at a given time, so it makes creating static files in the configuration kinda painful.
I tried taking off the readonly modifier and setting the following in the class constructor:
_log = LogManager.GetLogger("DataCollectionClass_" + deviceName + "_" + DateTime.Now.ToString("MMddyyyy"), typeof(SomeClassTypeHere));
But that requires that I define an appender manually in the configuration, which would be cumbersome and tough to keep up with.
Any thoughts on doing this in L4N? I have seen links here but don't really know if that much frameworking is necessary.
The code below shows how you can programatically configure log4Net without using a configuration file to achieve the effect you're looking for. Basically, it just involves creating a named logger and adding to the hierarchy.
I used as a starting point one of the answers from here.
log4net has a concept called logger hierarchy.
So you really should be creating your instance specific loggers with
.
characters instead of_
characters.Then in the configuration file reference the logger hierarchy like the following.
Notice how the logger name reference does not contain the fully qualified name used in code. It only references the root of the name. Think of it in the same way you think of namespaces.
I have an article that might help:
http://horth.com/blog/?p=165
This is about changing a logfile at runtime. What you could do is pass in the file name for each instance into your log4net file. That way you could create a log file for each instance of your class. This way your config file is simple and yet you have the flexibility to create a new log file for each class instance.
It was mentioned above that you could log to a database as well with indicators for each instance. If you don't wan to buy anything, use SQL Express which allows 10GB databases. You can even write directly to the MDF file instead of installing SQL.
Use the ADO.Net appender and log to a SQL Server database and just query for the information you need.
Another alternative is the log4net Dashboard: http://www.l4ndash.com/. It does a pretty decent job of integrating logs from various sources, and then slicing and dicing them in different ways. Reasonbly priced, too.