丰富Serlilogs具有独特价值的每个挂火工作
我使用Hangfire作为背景作业,Serilog作为伐木作业。我试图用TrackingId
来丰富我的serilogs,以便来自特定Hangfire作业的所有日志将具有相同的TrackingId
,我可以过滤它们。丰富Serlilogs具有独特价值的每个挂火工作
我Startup.cs
配置Serilog这样的:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(Configuration)
.WriteTo.Seq(serverUrl: serverUrl, apiKey: apiKey)
// Enrich the logs with a tracking id. Will be a new value per request
.Enrich.WithProperty("TrackingId", Guid.NewGuid())
.CreateLogger();
我入队的工作是这样的:
BackgroundJob.Enqueue<MyService>(myService => myService.DoIt(someParameter));
但是做这样不会将每迟发型工作单独TrackingId
。有什么办法可以达到这个目标吗?
对于什么是值得的,我最终使用服务器/客户端过滤器和GlobalJobFilters
注册如下所示。我碰到的一个令人讨厌的问题是AutomaticRetryAttribute
默认添加到GlobalJobFilters
集合中,并且该类3210没有在我们的定制JobLoggerAttribute
中创建的Serilog LogContext的知识。就我个人而言,我知道我只会允许手动重试,所以我只是删除了该属性并处理了IServerFilter.OnPerformed
方法中的错误。检查我的帖子的结尾,看看如何删除它,如果这对你有用。
如果你要允许自动重试,那么你将需要:1)创建装点AutomaticRetryAttribute
并使其意识到定制LogContext的自定义属性,2)再次从GlobalJobFilters
集合中删除默认AutomaticRetryAttribute
, 3)将你的装饰器属性添加到集合中。
public class JobLoggerAttribute : JobFilterAttribute, IClientFilter, IServerFilter
{
private ILogger _log;
public void OnCreating(CreatingContext filterContext)
{
_log = GetLogger();
_log.Information("Job is being created for {JobType} with arguments {JobArguments}", filterContext.Job.Type.Name, filterContext.Job.Args);
}
public void OnCreated(CreatedContext filterContext)
{
_log.Information("Job {JobId} has been created.", filterContext.BackgroundJob.Id);
}
public void OnPerforming(PerformingContext filterContext)
{
if (_log == null)
_log = GetLogger();
_log.Information("Job {JobId} is performing.", filterContext.BackgroundJob.Id);
}
public void OnPerformed(PerformedContext filterContext)
{
_log.Information("Job {JobId} has performed.", filterContext.BackgroundJob.Id);
if (filterContext.Exception != null)
{
_log.Error(
filterContext.Exception,
"Job {JobId} failed due to an exception.",
filterContext.BackgroundJob.Id);
}
_log = null;
}
private ILogger GetLogger()
{
return Log.ForContext(GetType()).ForContext("HangfireRequestId", Guid.NewGuid());
}
}
和登记...
GlobalJobFilters.Filters.Add(new JobLoggerAttribute());
卸下AutomaticRetryAttribute
...
var automaticRetryFilter = GlobalJobFilters.Filters.Where(x => x.Instance is AutomaticRetryAttribute).Single();
GlobalJobFilters.Filters.Remove(automaticRetryFilter.Instance);
这实际上是线程安全的吗? _log字段在工作线程中共享。 –
我有一个看看迟发型API并不能找到一种方法,轻松做到这一点;添加一个“服务器过滤器”似乎可能工作。 HTH。 –