This is probably too late to help you, but you could implement a filter. http://www.mail-archive.com/log4net-user%40logging.apache.org/msg02517.html shows how to implement a filter for limiting how often an exception is logged (if exception type is same as last exception type and if less than some specified amount of time has passed).
Here is the actual filter source code from that link:
public class ExceptionThrottleFilter : FilterSkeleton
{
private DateTime lastException = DateTime.MinValue;
private Type exceptionType = typeof(Exception);
private int threshold = 5; // seconds
public override void ActivateOptions()
{
base.ActivateOptions();
}
public override FilterDecision Decide(LoggingEvent loggingEvent)
{
if (loggingEvent.ExceptionObject != null && loggingEvent.ExceptionObject.GetType) == exceptionType)
{
if (loggingEvent.TimeStamp.Subtract(lastException).TotalSeconds > threshold)
{
lastException = loggingEvent.TimeStamp;
return FilterDecision.Accept;
}
else
{
return FilterDecision.Deny;
}
}
else
{
return FilterDecision.Neutral;
}
}
public Type ExceptionType
{
get { return exceptionType; }
set { exceptionType = value; }
}
public int Threshold
{
get { return threshold; }
set { threshold = value; }
}
}
It would be configured like this:
<filter type="Company.Project.Logging.ExceptionThrottleFilter">
<threshold value="2" />
<exceptionType value="System.ApplicationException" />
</filter>
It seems like it would be pretty straightforward to modify it to "throttle" messages that repeat. Maybe something like this (untested):
public class DuplicateMessageThrottleFilter : FilterSkeleton
{
private string lastMessage;
public override void ActivateOptions()
{
base.ActivateOptions();
}
public override FilterDecision Decide(LoggingEvent loggingEvent)
{
string newMessage;
if (loggingEvent.MessageObject != null)
{
newMessage = loggingEvent.MessageObject.ToString();
}
if (newMessage.Equals(lastMessage))
{
return FilterDecision.Deny;
}
lastMessage = newMessage;
return FilterDecision.Accept;
}
}
It might be nice to annotate a logged message with how many times it was repeated, but how to do that is not obvious to me:
Some message.
Some message.
Some message.
Look, a new message.
Some message.
Some message.
Look, a new message.
Could generate something like this:
Some message. (3 times)
Look, a new message.
Some message. (2 times)
Look, a new message.
Probably some kind of ForwardingAppender or BufferingForwardingAppender. It would always be one message behind. A message comes in. The "RepeatedMessageAppender" would hold that message. The next message comes in. If it is different than last message, forward last message to the "real" Appender (if "repeated count" is > 0, append the number to the last message before forwarding - this is the part that I am not sure about because I think htat it is not easy to modify the LoggingEvent that is passed to the Appender). If it is the same as the last message, increment counter and do not forward. Since the "RepeatedMessageAppender" is one behind, it probably has to be a BufferingForwardingAppender and it must implement Flush.
Maybe you (or someone else) will find this information useful.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…