丰富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。有什么办法可以达到这个目标吗?

+0

我有一个看看迟发型API并不能找到一种方法,轻松做到这一点;添加一个“服务器过滤器”似乎可能工作。 HTH。 –

对于什么是值得的,我最终使用服务器/客户端过滤器和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); 
+0

这实际上是线程安全的吗? _log字段在工作线程*享。 –