Clases base de registro de bucle indefinido de Serilog
¿Cómo puedo evitar crear un bucle con Serilog Sinks que quiero registrar?
El problema es que las clases base “MyTcpServer” y “MyTcpClient” utilizan Serilog.
Pero dado que TcpSink también utiliza las mismas clases, el envío de una entrada de registro dará lugar a un bucle infinito.
¿Cómo puedo evitar esto?
“`
Main()
{
Serilog.Log.Logger = new LoggerConfiguration()
.WriteTo.TcpSink() //esto es un TcpListener/Servidor que escucha en el puerto 1234
.WriteTo.Console()
.CreateLogger();
MyTcpServer AnotherServer = new MyTcpServer(4321);
}
public class MyTcpServer
{
///esta clase contiene Log.Verbose|Debug|Error
private List<mytcpclient> clients;
}
public class MyTcpClient
{
///esta clase contiene Log.Verbose|Debug|Error
}
public class TcpServerSink : ILogEventSink
{
MyTcpServer server;
public TcpServerSink(int port = 1234)
{
server = new MyTcpServer(1234);
}
public void Emit(LogEvent logevent)
{
string str = Newtonsoft.Json.JsonConvert.Serialize(logevent);
server.Send(str);
}
}
“`
davy.ai
Para evitar crear un bucle con los Sinks de Serilog, como en el fragmento de código dado donde tanto la clase TcpServer como la clase TcpClient utilizan Serilog, una solución es envolver el TcpSink en una clase que bloquee los intentos de registro de las clases TcpServer y TcpClient. Aquí tienes un ejemplo de implementación:
En esta solución, creamos una clase envolvente
TcpSinkWrapper
que toma una instancia deTcpSink
como argumento del constructor. En el métodoEmit
, comprobamos si el origen del evento es alguna de las clasesTcpServer
oTcpClient
examinando la propiedadSourceContext
delLogEvent
. Si lo es, descartamos el evento y retornamos temprano. De lo contrario, pasamos el evento a la instancia envuelta deTcpSink
para emitirlo de forma normal.Finalmente, actualizamos la configuración del logger para utilizar la clase envolvente en lugar del
TcpSink
directamente.