Zeitweiliges Problem mit gesperrten log4net RollingFileAppender-Dateien

113

Bei Entwicklungs- und Produktionsmaschinen tritt zeitweise ein Problem auf, bei dem unsere Protokolldateien nicht protokolliert werden.

Bei der Entwicklung und beim Debuggen mit Visual Studio werden im VS-Ausgabefenster die folgenden log4net-Fehlermeldungen angezeigt:

log4net:ERROR [RollingFileAppender] Unable to acquire lock on file C:\folder\file.log.

Der Prozess kann nicht auf die Datei 'C: \ folder \ file.log' zugreifen, da sie von einem anderen Prozess verwendet wird.

log4net:ERROR XmlConfigurator: Failed to find configuration section 'log4net' in the application's .config file.
Check your .config file for the <log4net> and <configSections> elements.

Der Konfigurationsabschnitt sollte folgendermaßen aussehen:

<section
  name="log4net"
  type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />

Unsere aktuelle Problemumgehung besteht darin, die letzte Protokolldatei umzubenennen. Wir würden natürlich erwarten, dass dies fehlschlägt (aufgrund der oben genannten Dateisperre), aber normalerweise nicht. Ein- oder zweimal ist die Umbenennung aufgrund einer Sperre des Prozesses aspnet_wp.exe fehlgeschlagen .

Unser log4net-Konfigurationsabschnitt ist unten dargestellt:

<log4net>
  <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
    <file value="C:\folder\file.log"/>
    <appendToFile value="true" />
    <datePattern value="yyyyMMdd" />
    <rollingStyle value="Date" />
    <maximumFileSize value="10MB" />
    <maxSizeRollBackups value="100" />
    <layout type="log4net.Layout.PatternLayout">
      <header value="[Header]&#xA;"/>
      <footer value="[Footer]&#xA;"/>
      <conversionPattern value="%date %-5level %logger ${COMPUTERNAME} %property{UserHostAddress} [%property{SessionID}] - %message%newline"/>
    </layout>
  </appender>
  <root>
    <level value="INFO"/>
    <appender-ref ref="RollingLogFileAppender"/>
  </root>
</log4net>

Wie bereits erwähnt, tritt dies zeitweise auf Computern auf, aber sobald das Problem auftritt, bleibt es bestehen.

Richard Ev
quelle

Antworten:

172

Versuchen Sie es hinzuzufügen

<lockingModel type = "log4net.Appender.FileAppender + MinimalLock" />

zu deinem <appender />Element. Es gibt einige Leistungseinbußen, da dies bedeutet, dass log4net die Datei für jeden Schreibvorgang sperrt, in sie schreibt und entsperrt (im Gegensatz zum Standardverhalten, bei dem die Sperre für eine lange Zeit erfasst und beibehalten wird).

Eine Implikation des Standardverhaltens besteht darin, dass, wenn Sie es unter einer Website verwenden, die unter mehreren Arbeitsprozessen ausgeführt wird, die auf demselben Computer ausgeführt werden, jeder versucht, diese Sperre auf unbestimmte Zeit zu erfassen und beizubehalten, und zwei davon Ich werde einfach verlieren. Das Ändern des Sperrmodells auf die minimale Sperre umgeht dieses Problem.

(Beim Debuggen sind unansehnliche Abbrüche und das Hochfahren vieler neuer Worker-Prozesse genau das, was wahrscheinlich passieren wird.)

Viel Glück!

Nicholas Piasecki
quelle
Ersparte mir viel Kopfkratzen, warum mein Logger zeitweise arbeitete. Ich habe Worker-Prozesse zum App-Pool hinzugefügt, duh!
RhinoDevX64
Ich verwende dies in einem Dienst und zusätzlich zu dieser Änderung hat der Benutzer, den der Dienst ausgeführt hat, die erforderliche Berechtigung zum Schreiben. Vielen Dank!
LowTide
Vielen Dank, viel Zeit gespart.
Siva
2
Ich möchte nur die Datei lesen, aber log4net sperrt auch zum Lesen ... es könnte nur zum Schreiben
gesperrt
37

Beachten Sie auch die log4net-FAQ :

Wie kann ich mehrere Prozesse dazu bringen, sich in derselben Datei anzumelden?

Bevor Sie überhaupt eine der angebotenen Alternativen ausprobieren, fragen Sie sich, ob wirklich mehrere Prozesse in derselben Datei protokolliert werden müssen, und tun Sie es dann nicht ;-).

FileAppender bietet steckbare Sperrmodelle für diesen Anwendungsfall, aber alle vorhandenen Implementierungen weisen Probleme und Nachteile auf.

Standardmäßig verfügt der FileAppender während der Protokollierung über eine exklusive Schreibsperre für die Protokolldatei. Dies verhindert, dass andere Prozesse in die Datei schreiben. Es ist bekannt, dass dieses Modell mit (zumindest in einigen Versionen von) Mono unter Linux zusammenbricht und Protokolldateien möglicherweise beschädigt werden, sobald ein anderer Prozess versucht, auf die Protokolldatei zuzugreifen.

MinimalLock erhält die Schreibsperre nur, während ein Protokoll geschrieben wird. Dies ermöglicht es mehreren Prozessen, Schreibvorgänge in dieselbe Datei zu verschachteln, wenn auch mit einem erheblichen Leistungsverlust.

InterProcessLock sperrt die Datei überhaupt nicht, sondern synchronisiert sie mit einem systemweiten Mutex. Dies funktioniert nur, wenn alle Prozesse zusammenarbeiten (und dasselbe Sperrmodell verwenden). Der Erwerb und die Freigabe eines Mutex für jeden zu schreibenden Protokolleintrag führt zu einem Leistungsverlust. Der Mutex ist jedoch der Verwendung von MinimalLock vorzuziehen.

Wenn Sie RollingFileAppender verwenden, wird es noch schlimmer, da mehrere Prozesse möglicherweise versuchen, die Protokolldatei gleichzeitig zu rollen. RollingFileAppender ignoriert das Sperrmodell beim Rollen von Dateien vollständig. Rollende Dateien sind mit diesem Szenario einfach nicht kompatibel.

Eine bessere Alternative besteht darin, Ihre Prozesse bei RemotingAppenders protokollieren zu lassen. Mit dem RemoteLoggingServerPlugin (oder IRemoteLoggingSink) kann ein Prozess alle Ereignisse empfangen und in einer einzigen Protokolldatei protokollieren. Eines der Beispiele zeigt, wie das RemoteLoggingServerPlugin verwendet wird.

Ciprian Teiosanu
quelle
6

Wenn Sie haben

<staticLogFileName value="true" />
<rollingStyle value="Date" />
<datePattern value="yyyyMMdd" />

und hinzufügen

<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

dann tritt ein Fehler auf, während das Rollen stattfindet. Der erste Prozess erstellt die neue Datei und benennt die aktuelle Datei um. Dann machen die nächsten Prozesse dasselbe und nehmen die neu erstellte Datei und überschreiben die neu umbenannte Datei. Das Ergebnis ist, dass der Logfiel für den letzten Tag leer ist.

Jonte
quelle
1
Dies gilt nur, wenn mehrere Prozesse auf dieselbe fortlaufende Datei zugreifen. Es ist innerhalb des gleichen Prozesses sicher. hectorcorrea.com/blog/log4net-thread-safe-but-not-process-safe
Mike Chamberlain
@MikeChamberlain Laut OP (siehe seinen Kommentar zur Antwort) werden mehrere Mitarbeiter gleichzeitig arbeiten und log4net zum Protokollieren verwenden. Daher ist dieses Problem relevant!
Seebiscuit