log4net BufferingForwardingAppender performance-Problem

EDIT 2 : ich habe das problem gelöst (siehe Antwort unten) Bitte beachten Sie, dass das problem potenziell betroffen sind alle appenders verziert mit BufferingForwardingAppender sowie allen appenders Erben von BufferingAppenderSkeleton (beziehungsweise : AdoNetAppender, RemotingAppender, SmtpAppender und SmtpPickupDirAppender) *

War ich dabei einige sehr basic-Bänke von log4net und ich versuchte, Sie zu schmücken, RollingFileAppender mit einem BufferingForwardingAppender.

Erlebe ich schreckliche Leistung werde durch die BufferingForwardingAppender statt direkt durch den RollingFileAppender und ich weiß wirklich nicht, was der Grund ist.

Hier ist meine Konfiguration:

<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
  <file value="c:\" />
  <appendToFile value="false" />
  <rollingStyle value="Composite" />
  <datePattern value="'.'MMdd-HH'.log'" />
  <maxSizeRollBackups value="168" />
  <staticLogFileName value="false" />
  <layout type="log4net.Layout.PatternLayout">      
    <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
  </layout>
</appender>

<appender name="BufferingForwardingAppender" type="log4net.Appender.BufferingForwardingAppender">
  <bufferSize value="512" />
  <appender-ref ref="RollingLogFileAppender" />
</appender>

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

Und hier ist der benchmark (sehr einfacher code):

var stopWatch = new Stopwatch();
stopWatch.Start();            
for (int i = 0; i < 100000; i++)            
{
   Log.Debug("Hello");
}
stopWatch.Stop();
Console.WriteLine("Done in {0} ms", stopWatch.ElapsedMilliseconds);

Geht direkt durch RollingFileAppender die Ausgabe ist:

Getan 511 ms

Während werde durch die BufferingForwardingAppender Dekoration der RollingFileAppender :

Getan 14261 ms

Ist ca 30 mal langsamer.

Ich dachte, ich würde gewinnen einige Geschwindigkeit durch die Pufferung eine bestimmte Menge von log, bevor das schreiben auf die Datei, aber für einige Grund wird es die Dinge viel schlimmer.

Scheint mir, wie die Konfiguration ist OK, also das ist wirklich seltsam.

Hat jemand eine Ahnung?

Dank!

EDIT 1 :

Das Verhalten ist genau das gleiche durch umwickeln/verzieren einen FileAppender oder sogar ConsoleAppender (es gibt noch ein Beispiel von basic BufferingForwardingAppender Verpackung/Dekoration ConsoleAppender in log4net offiziellen config Proben .. und nichts spezifisches erwähnt, Umgang mit Leistung).

Nachdem einige Untersuchung/Profilierung, ich kann sehen, dass die Mehrheit der Zeit verdorben ist, innerhalb der BufferingForwardingAppender genauer gesagt in einem Aufruf WindowsIdentity.GetCurrent() ... aufgerufen wird, JEDES mal, wenn wir anrufen um zu Log.Debug() .. im vorherigen Beispiel (100K mal in die sample-Quelle oben).

Aufrufe dieser Methode sind dafür bekannt, sehr teuer und sollten vermieden oder minimiert werden, ich weiß wirklich nicht, warum es wird genannt für jedes Ereignis protokollieren.
Bin ich wirklich komplett misconfiguring etwas /nicht zu sehen, etwas deutlicher, oder ist dass ein bug, der irgendwie und irgendwo, das ist, was ich versuche jetzt...

Die teilweise call-stack ist :

  • AppenderSkeleton.DoAppend
  • BufferingAppenderSkeleton.Append
  • LoggingEvent.FixVolatileData
  • LoggingEvent.get_UserName()

Einen Anruf zu get_LocationInformation() ist auch in FixVolatileData, dass ein high-perf-Kosten (Erfassung der stack-trace jedes mal).

Ich versuche jetzt zu verstehen, warum das so extrem teuer FixVolatileData nennen (zumindest für das Update gebeten werden) geschieht, für jedes Ereignis protokollieren in diesem Zusammenhang in der Erwägung, dass geht direkt durch die gewickelten appender (direkt über ConsoleAppender/FileAppender ..) nicht der Durchführung dieser Art von operation.

Kommenden update Folgen, es sei denn, jemand hat eine Antwort auf alle diese 😉

Dank!

InformationsquelleAutor darkey | 2012-07-03
Schreibe einen Kommentar