Tengo un error interesante al usar Serilog SelfLog . el error es:
Application: XXX.exe Framework Version: v4.0.30319 Description: The process was terminated due to an unhandled exception. Exception Info: System.IO.IOException at System.IO.__Error.WinIOError(Int32, System.String) at System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean, Boolean, Boolean) at System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions, System.String, Boolean, Boolean, Boolean) at System.IO.StreamWriter.CreateFile(System.String, Boolean, Boolean) at System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32, Boolean) at System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding) at System.IO.File.InternalAppendAllText(System.String, System.String, System.Text.Encoding) at Serilog.Debugging.SelfLog.WriteLine(System.String, System.Object, System.Object, System.Object) at Serilog.Sinks.PeriodicBatching.PeriodicBatchingSink+<OnTick>d__16.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task) at Serilog.Sinks.PeriodicBatching.PortableTimer+<OnTick>d__8.MoveNext() at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() at System.Threading.ThreadPoolWorkQueue.Dispatch()No tengo idea de lo que sucede. Tengo .Net framework 4.6.1 , Serilog versión 2.9.0 y no puedo volver a producir el error.
Por favor, ¿pueden ayudarme a describir el error? ¿Por qué recibí el error? ¿Conoces alguna solución para este error?
Yo uso las bibliotecas a continuación:
EDITAR: Mi aplicación conf aquí:
<?xml version="1.0" encoding="utf-8"?> <configuration> <appSettings> <add key="serilog:minimum-level" value="Verbose" /> <add key="serilog:using:Console" value="Serilog.Sinks.Console" /> <add key="serilog:write-to:Console" /> <add key="serilog:using:Http" value="Serilog.Sinks.Http" /> <add key="serilog:write-to:Http.requestUri" value="http://log.XXX.com:8080/TestEngine" /> <add key="serilog:write-to:Http.batchPostingLimit" value="1" /> <add key="serilog:write-to:Http.batchFormatter" value="Serilog.Sinks.Http.BatchFormatters.ArrayBatchFormatter, Serilog.Sinks.Http" /> <add key="serilog:enrich:with-property:application" value="TestEngine" /> </appSettings> <startup> ...Integración de Serilog aquí:
var config = new LoggerConfiguration() .Enrich.FromLogContext() .Enrich.WithMachineName() .Enrich.WithUserName() .ReadFrom.AppSettings(); if (CustomLogContext == null) { CustomLogContext = new Dictionary<string, object>(); } foreach (var logContext in CustomLogContext) { config.Enrich.WithProperty(logContext.Key, logContext.Value); } if (!string.IsNullOrEmpty(CustomLogFileFullName)) { config = config.WriteTo.File($"{CustomLogFileFullName}"); } Serilog.Log.Logger = config.CreateLogger(); Serilog.Debugging.SelfLog.Enable(msg => File.AppendAllText("internallog.log", msg, Encoding.UTF8)); ILoggerProvider loggerProvider = new SerilogLoggerProvider(Serilog.Log.Logger); _logger = loggerProvider.CreateLogger("XXX.Logging.Serilog");SOLUCIÓN: como dice @RubenBartelink, si usa Selflog pero usa archivos de registro personalizados, corre algunos riesgos. Debido a que Serilog puede no escribir un archivo personalizado y puede ser que Serilog arroje una excepción de E/S. Este problema no pertenece a Serilog. El problema es en realidad la operación File.AppendAlltext. La solución es la siguiente:
Serilog.Debugging.SelfLog.Enable(msg => { try { File.AppendAllText("internallog.log", msg, Encoding.UTF8); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } });Como se mencionó en el comentario de @Daniel A. White, está haciendo algo arriesgado: intentar escribir en un archivo, en un controlador que se proporciona "si todo lo demás falla". Algunos ejemplos:
SelfLog )Si bien la página Wiki de depuración y diagnóstico de Serilog actualmente muestra un ejemplo de cómo escribir en un archivo, esa simplemente no es la naturaleza del contrato: no debe fallar.
Por lo tanto, si realmente desea emitir SelfLog a un archivo, deberá agregar un try / catch y tragar la excepción en el controlador.
Diría que es un valor bastante cuestionable tener un archivo como respaldo cuando File Sink es su salida principal. Esto es doblemente el caso, ya que no tiene ningún mecanismo para asegurarse de que se recorte (imagine que tiene un registro de bucle cerrado con una cadena de mensaje mal formada; eventualmente llenaría su disco).
Personalmente, he manejado esta compensación haciendo eco del SelfLog en mi Console Sink (que el registro no arrojará, según lo anterior) sobre la base de que se puede confiar en el entorno operativo (piense en Kubernetes) para capturarlo o alertarlo.