I ended up doing my own appender filter, which allows setting a lower matching level for explicitly specified loggers:
public class MultipleLevelFilter : LevelMatchFilter
{
public MultipleLevelFilter()
{
LevelToMatchForSpecificLoggers = Level.Fatal;
_specificLoggers = new string[0];
}
/// <summary>
/// Gets or sets the level to match for loggers
/// specified in the <see cref="SpecificLoggers"/> property.
/// </summary>
/// <value>The level to match for specific loggers.</value>
public Level LevelToMatchForSpecificLoggers { get; set; }
private string[] _specificLoggers;
/// <summary>
/// Gets or sets a comma separated list of "specific" loggers.
/// For these loggers, <see cref="LevelToMatchForSpecificLoggers"/>
/// property is checked to see whether they should be logged.
/// </summary>
/// <value>The specific loggers.</value>
public string SpecificLoggers
{
get { return string.Join(",", _specificLoggers); }
set
{
_specificLoggers = value.Split(',').Select(s=>s.Trim()).ToArray();
}
}
/// <summary>
/// Tests if filter matches the specified logging event.
/// </summary>
/// <param name="loggingEvent">the event to filter</param>
public override FilterDecision Decide(LoggingEvent loggingEvent)
{
// if base.LevelToMatch is matched, always match
if (loggingEvent.Level >= LevelToMatch)
return AcceptOnMatch ? FilterDecision.Accept : FilterDecision.Deny;
// if specific level is matched, check if logger name matches
if (loggingEvent.Level >= LevelToMatchForSpecificLoggers)
{
string name = loggingEvent.LoggerName;
for (int i = 0; i < _specificLoggers.Length; i++)
if (name == _specificLoggers[i])
return AcceptOnMatch ?
FilterDecision.Accept : FilterDecision.Deny;
}
// continue with next filter
return FilterDecision.Neutral;
}
}
Usage:
<appender name="Smtp_Appender"
type="Ster.Log4Net.DelayedSendSmtpAppender">
<!-- ... common properties (from, to, etc) -->
<!-- our custom filter -->
<filter type="MyNamespace.MultipleLevelFilter">
<!-- this level is ALWAYS matched -->
<levelToMatch value="ERROR" />
<!-- this level is matched only for specific loggers -->
<levelToMatchForSpecificLoggers value="INFO" />
<!-- these are the "specific" loggers (comma separated) -->
<specificLoggers value="SomeLogger, SomeOtherLogger" />
</filter>
<!-- always end the filter chain with DenyAll -->
<filter type="log4net.Filter.DenyAllFilter" />
</appender>
<root>
<priority value="INFO" />
<appender-ref ref="File_Appender" />
<appender-ref ref="Smtp_Appender" />
</root>