Is there a way to have log4net change the target location of the intended log thru certain conditions in the program, without having to update and redeploy the xml config?
I dont want any configuration dependent solution. It should work purely thru code. I have certain conditions based on which I will be able to tell my program which target to choose. On some condition the program will automatically switch between a text file on a pre-defined path or to SQL Server on a predefined server/database or to an event log under my application suite's name. File path, sql connection string and event log parameters will be the only thing stored in my applications config file.
Is this even doable on log4net? I couldn't find anything relevant with what I searched so I don't have any code I can show yet. Most answers were on how to change the default directory location, but thats not what I want.
Thanks
I know you talked about changing your appender in code only, but I really think you would benefit more by using appenders chosen depending on a context property set in the code
An example would be to do something like this in your configuration file:
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender,log4net">
<filter type="log4net.Filter.PropertyFilter">
<key value="target" />
<stringToMatch value="DB" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<!-- your ado configuration -->
<appender name="AnotherAppender" type="log4net.Appender.EventLogAppender,log4net">
<filter type="log4net.Filter.PropertyFilter">
<key value="target" />
<stringToMatch value="EventLog" />
<acceptOnMatch value="true" />
</filter>
<filter type="log4net.Filter.DenyAllFilter" />
<!-- your Eventlog configuration -->
Then in your code, you can set the logger target
property to the destination you want:
var isDB = true;
var loggingEvent = new LoggingEvent(typeof(Program), Log.Logger.Repository, Log.Logger.Name, Level.Info, "message", null);
loggingEvent.Properties["target"] = isDB ? "DB" : "EventLog";
Log.Logger.Log(loggingEvent);
This way you don't have magic logging outputs hidden in your code, the outputs are driven through configuration so you can change it easily, and the routing is the only thing you have to take care of inside the application.
If you don't need the context per message (for example you know that once logging routing changes, it won't switch again for a long time), you can use one of the three other contexts that can be set globally:
log4net.GlobalContext
is used for all loggers in the applog4net.ThreadContext
is shared between loggers in the same threadlog4net.
ThreadLogicalContext is shared between loggers in the same logical boundaries for a thread (more info on the difference)