locking log4net rollingfileappender

locking - Problema de archivo bloqueado de log4net RollingFileAppender intermitente



(3)

Estamos viendo un problema intermitente en las máquinas de desarrollo y producción por el cual nuestros archivos de registro no se registran.

Cuando se ejecuta en desarrollo y depuración usando Visual Studio obtenemos los siguientes mensajes de error de log4net en la ventana de salida de VS:

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

El proceso no puede acceder al archivo ''C: / carpeta / archivo.log'' porque lo está utilizando otro proceso.

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.

La sección de configuración debe verse así:

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

Nuestra solución actual para el problema es cambiar el nombre del último archivo de registro. Por supuesto, esperaríamos que esto fallara (debido al bloqueo de archivo antes mencionado), pero normalmente no es así. Una o dos veces, el cambio de nombre ha fallado debido a un bloqueo del proceso aspnet_wp.exe .

Nuestra sección de configuración de log4net se muestra a continuación:

<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>

Como se mencionó, estamos viendo esto intermitentemente en las máquinas, pero una vez que ocurre el problema, persiste.


Prueba agregar

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

a su elemento <appender /> . Hay cierto impacto en el rendimiento porque esto significa que log4net bloqueará el archivo, lo escribirá y lo desbloqueará para cada operación de escritura (en oposición al comportamiento predeterminado, que adquiere y conserva el bloqueo durante mucho tiempo).

Una consecuencia del comportamiento predeterminado es que si lo está utilizando en un sitio web que se está ejecutando en múltiples procesos de trabajo que se ejecutan en la misma máquina, cada uno tratará de adquirir y mantener ese bloqueo indefinidamente, y dos de ellos son solo voy a perder Cambiar el modelo de bloqueo al bloqueo mínimo soluciona este problema.

(Cuando la depuración, las terminaciones desagradables y la rotación de muchos procesos de trabajo nuevos son exactamente el tipo de cosas que es probable que suceda).

¡Buena suerte!


Si usted tiene

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

y añadir

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

entonces habrá un error mientras ocurre la rotación. El primer proceso creará el nuevo archivo y cambiará el nombre del archivo actual. Luego el próximo proceso hará lo mismo y tomará el archivo recién creado y sobrescribirá el archivo recién renombrado. Como resultado, el logfiel del último día está vacío.


También tenga en cuenta las preguntas más frecuentes de log4net :

¿Cómo consigo múltiples procesos para iniciar sesión en el mismo archivo?

Antes incluso de comenzar a probar cualquiera de las alternativas provistas, pregúntese si realmente necesita tener múltiples procesos para iniciar sesión en el mismo archivo, luego no lo haga ;-).

FileAppender ofrece modelos de bloqueo conectables para este uso, pero todas las implementaciones existentes tienen problemas y desventajas.

De forma predeterminada, FileAppender tiene un bloqueo de escritura exclusivo en el archivo de registro mientras se está registrando. Esto evita que otros procesos escriban en el archivo. Se sabe que este modelo se rompe con (al menos en algunas versiones de) Mono en Linux y los archivos de registro pueden corromperse tan pronto como otro proceso intente acceder al archivo de registro.

MinimalLock solo adquiere el bloqueo de escritura mientras se escribe un registro. Esto permite múltiples procesos para intercalar escrituras en el mismo archivo, aunque con una pérdida considerable de rendimiento.

InterProcessLock no bloquea el archivo en absoluto, sino que sincroniza usando un Mutex ancho de todo el sistema. Esto solo funcionará si todos los procesos cooperan (y usan el mismo modelo de bloqueo). La adquisición y publicación de un Mutex para cada entrada de registro que se escribirá dará como resultado una pérdida de rendimiento, pero el Mutex es preferible al uso de MinimalLock.

Si utiliza RollingFileAppender las cosas empeorarán, ya que varios procesos pueden intentar comenzar a rodar el archivo de registro al mismo tiempo. RollingFileAppender ignora completamente el modelo de bloqueo cuando se mueven los archivos, simplemente no es compatible con este escenario.

Una mejor alternativa es hacer que sus procesos se registren en RemotingAppenders. Al utilizar RemoteLoggingServerPlugin (o IRemoteLoggingSink), un proceso puede recibir todos los eventos y registrarlos en un único archivo de registro. Uno de los ejemplos muestra cómo usar el RemoteLoggingServerPlugin.