Serilog无限循环日志记录基类



如何避免使用要记录的Serilog Sinks创建循环。问题是基类";MyTcpServer";以及";MyTcpClient";使用序列号。但由于TcpSink也使用相同的类,发送日志条目将无限循环。

如何防止这种情况发生?

Main()
{
Serilog.Log.Logger = new LoggerConfiguration()
.WriteTo.TcpSink() //this a TcpListener/Server listening on port 1234
.WriteTo.Console()
.CreateLogger();
MyTcpServer AnotherServer = new MyTcpServer(4321);
}
public class MyTcpServer
{
///this class contains Log.Verbose|Debug|Error
private List<MyTcpClient> clients;
}
public class MyTcpClient
{
///this class contains 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);
}
}

这里只有两个选项

  • TcpServerSink中使用MyTcpServer,但不登录到TcpServerSink
  • 不要在TcpServerSink中使用MyTcpServer

对于第一个解决方案,使MyTcpServer依赖于ILogger,而不是使用静态Log依赖。通过这种方式,你可以通过任何你想要的记录器,或者只是在你的水槽中禁用日志记录:

server = new MyTcpServer(SilentLogger.Instance, 1234);

我个人更喜欢第二种解决方案。因为您应该只记录与应用程序逻辑相关的事件到Serilog接收器。TcpServerSink与应用程序逻辑无关。在其他Serilog接收器中使用的一种常见方法是使用静态SelfLog写入某些TextWriter。例如

SelfLog.Out = Console.Error;

然后你可以使用这个自我日志来写一些关于你的水槽的信息。此外,你的水槽应该使用类似普通TcpClient的东西,而不是MyTcpServer。您可以查看Splunk-TcpSink示例。

值得考虑的一个选项是在TCP服务器内登录时使用Log.ForContext<MyTcpServer>()

Log.ForContext<MyTcpServer>().Information("Hello!");

并为TCP接收器过滤掉这些消息:

// dotnet add package Serilog.Expressions
.WriteTo.Conditional(
"SourceContext not like 'MyNamespace.MyTcpServer%'",
wt => wt.TcpSink())
.WriteTo.Console()

这样做的优点是可以将错误从TCP接收器发送到控制台,但缺点是,如果忘记在TCP服务器内使用上下文记录器,仍然会出现堆栈溢出。

相关内容

  • 没有找到相关文章

最新更新