问题
How do I programmatically check that IsEnabledFor
is true
for a certain appender filter.
This is my config:
<log4net>
<root>
<level value="ALL" />
<appender-ref ref="appender" />
</root>
<appender name="appender" type="log4net.Appender.FileAppender">
<filter type="log4net.Filter.LevelRangeFilter">
<levelMin value="ERROR" />
<levelMax value="FATAL" />
</filter>
</appender>
<log4net>
Ok so if I set <root>
Level to say ERROR
and I do a IsEnabledFor
(Debug) it returns true
but if I set <root>
level to ALL
and add filters to the appender its not taking into account the filters.
How do I get it to include appender filters or is there another way to query this ?
回答1:
I could be wrong, but I do not see how this can be done easily. What you could do is something like this:
var hierarchy = LogManager.GetRepository() as Hierarchy;
if(hierarchy != null)
{
var appenders = hierarchy.GetAppenders();
foreach( IAppender appender in appenders)
{
var appenderSkeleton = a as AppenderSkeleton
if (appenderSkeleton != null)
{
IFilter filterHead = appenderSkeleton.FilterHead;
// now analyse the filter chain
}
}
}
I did not test this code, but it should work more or less. What you get this way is the head of any configured filter chain for all appenders that derive from AppenderSkeleton
. The head of the filter chain implements IFilter
(as do all filters) and it contains one method and a property:
FilterDecision Decide(LoggingEvent loggingEvent);
IFilter Next { get; set; }
Now you could create an instance of a LoggingEvent
with the log level you are interested in, and go through the filter chain by using the Next
property and test each filter by calling FilterDecision
.
This tells you if the appender would accept or deny the logging event, but you need to be aware that an appender might also filter based on other criteria (e.g. message content) and thus it would not exactly be an "IsEnabledFor" implementation.
回答2:
I know this is an old post, but Stefan's answer helped be construct the following. My use case was a custom Logging Level for Performance of a given operations. Obviously we required the ability to toggle this level.
In my particular case we are only using the LevelMatchFilter so we wouldn't run into the issues you would with the other filter types...
/// <summary>
/// evaulates if a custom log level is enabled.
/// </summary>
/// <param name="log"></param>
/// <param name="level"></param>
/// <returns></returns>
public static bool IsLevelEnabled(this log4net.ILog log, log4net.Core.Level level)
{
var hierarchy = log4net.LogManager.GetRepository() as log4net.Repository.Hierarchy.Hierarchy;
if (hierarchy != null)
{
var appenders = hierarchy.GetAppenders();
foreach (log4net.Appender.IAppender appender in appenders)
{
var appenderSkeleton = appender as log4net.Appender.AppenderSkeleton;
if (appenderSkeleton != null)
{
log4net.Filter.IFilter filterHead = appenderSkeleton.FilterHead;
//traverse the filter chain
var currentFilter = filterHead;
while (currentFilter.Next != null)
{
if (currentFilter is log4net.Filter.LevelMatchFilter)
{
//if the filter level matches the target
if (((log4net.Filter.LevelMatchFilter)currentFilter).LevelToMatch == level)
{
return true;
}
}
//move to the next filter
currentFilter = currentFilter.Next;
}
}
}
}
return false;
}
来源:https://stackoverflow.com/questions/10124896/log4net-programmatically-check-isenabledfor-for-appender-filters