我们有一个Windows服务,它创建一个新线程并每天运行一次预定任务。日志记录是用Serilog完成的,接收器是Splunk ("Serilog.Sinks.Splunk")。在成功运行期间,我们向日志(Log.Information("") )写入8条信息消息。除了时间戳和整数值之外,消息在一次运行到另一次运行时大致相同。在完成实际作业任务之前记录四条消息,在完成后记录四条消息。
我们发现,有时所有八条消息都出现在Splunk中,有时只有最后四条消息(那些在耗时处理之后记录的消息已经完成),有时没有一条消息。
当我们添加另一个接收器,写入文件("Serilog.Sinks.File")时,我们总是会得到文件中的所有八条消息。
添加Serilog调试日志记录(Serilog.Debugging.SelfLog.Enable)时,当日志消息被丢弃时,我们会得到以下调试消息:"2019-08-30T11:28:03.9029821Z --当试图将事件发送到Serilog.Debugging.SelfLog.Enable时,收到了禁止的状态代码,事件已被丢弃,不会被放回队列中。“
在计划的任务中添加一个睡眠(System.Threading.Thread.Sleep() ),我们总是在Splunk之后完成日志记录,因此似乎需要一些时间来设置到Splunk端点的连接,并且在连接启动之前发送的任何消息都会被丢弃。由于其中三条消息是在执行进入我们的代码之前由外部nuget包(Hangfire)记录的,所以我们经常丢失这三条消息,因此在代码中使用Sleep()并不理想。
伪代码(包括睡眠),正如我所描述的日志消息1-3 (和6-8)是由外部nuget包编写的:
public Task DoJob()
{
var currentRunInformation = new RunInformation();
try
{
System.Threading.Thread.Sleep(3000);
Log.Information($"Log message 4");
//Get Data
var jobData = GetJobData();
//Do some calculations
var calculated = DoCalculations(jobData);
//Save result
PersistResult(calculated);
Log.Information($"Log message 4");
return Task.CompletedTask;
}
catch (Exception exception)
{
Log.Error(exception, $"Error log");
return Task.FromException(exception);
}
}在发送消息之前,我们是否可以让日志记录等待打开的连接?或者其他避免以不可预测的方式丢弃日志的选项?
发布于 2019-09-06 01:26:05
在Serilog.Sinks.Splunk中没有任何东西可以在发送消息之前对Splunk执行额外的检查,或者重试失败的消息。您可以跟踪本期,以便在将来实现时得到通知。
幕后,接收器只是向Splunk事件收集器发送HTTP请求.
要实现您想要的行为,您必须实现Serilog.Sinks.Splunk的一个变体。您可能可以从耐久原木运输的实现中借用Serilog.Sinks.Seq,并存储未能在文件中发送的消息,然后稍后重试.
ps:很有趣,即使是显示如何使用水槽的代码样本,在发送消息给Splunk一个热身的机会之前也有一个Thread.Sleep .
https://stackoverflow.com/questions/57801885
复制相似问题