Lossy logging, also receive messages after an error?

False logging in log4net is great for getting information about events leading to an error with minimal loss of performance. However, it would often be interesting to register a few messages later , to make sure that the system processed it as planned. How can I do that?

+3
source share
2 answers

I would write a custom version of BufferingForwardAppender that would log a custom number of messages after an error. Basically you turn off "be lost" after an error for a while and forward all messages directly.

Note. Make sure that the application immediately discards messages when an error is logged, because you cannot be sure that other messages will appear after the error.

+5
source

The accepted answer worked like a charm. To simplify, I did not separately configure the number of messages after the error. Instead, one full buffer + 1 is sent losslessly after a start message. The code:

public class BufferingForwardingAppenderEx : BufferingForwardingAppender
{
    /// <summary>
    /// If in lossy-mode, set the appender to non-lossy after a send has been done to get what happended after.
    /// </summary>
    public bool NonLossyAfterTriggered { get; set; }

    // Flag that tells if the appender is currently in non-lossy-override-mode
    private bool _nonLossyOverride = false;

    protected override void SendBuffer(global::log4net.Core.LoggingEvent[] events)
    {
        if (NonLossyAfterTriggered)
        {
            SetLossyAccordingToReasonForSending(events);
        }

        base.SendBuffer(events);
    }

    private void SetLossyAccordingToReasonForSending(LoggingEvent[] events)
    {
        if (_nonLossyOverride)
        {
            var newestEvent = events[events.Length - 1];
            var bufferIsSentBecauseItIsFull = !Evaluator.IsTriggeringEvent(newestEvent);

            if (bufferIsSentBecauseItIsFull)
            {
                _nonLossyOverride = false;
                Lossy = true;
            }
        }
        else
        {
            _nonLossyOverride = true;
            Lossy = false;
        }
    }
}

And here is an example of how it is configured:

<appender name="BufferingForwardingAppender"
          type="Foo.log4net.BufferingForwardingAppenderEx">
  <bufferSize value="3"/>
  <lossy value="true"/>
  <nonLossyAfterTriggered value="true" />
  <evaluator type="log4net.Core.LevelEvaluator">
    <threshold value="WARN"/>
  </evaluator>
  <appender-ref ref="ConsoleAppender"/>
</appender>

<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
  <layout type="log4net.Layout.PatternLayout">
    <conversionPattern
      value="%date{yyyy-MM-dd HH:mm:ss} %-5level %-13logger{1} %message%newline"/>
  </layout>
</appender>

<root>
  <level value="DEBUG"/>
  <appender-ref ref="BufferingForwardingAppender"/>
</root>

With this configuration, a single warning (or, even worse) is preceded by 2, and then 4 messages.

+4
source

All Articles