丰富 Serlilogs,为每个 Hangfire 作业提供独特的价值

2024-01-06

我使用 Hangfire 进行后台作业,使用 Serilog 进行日志记录。我正在尝试用以下内容来丰富我的序列日志TrackingId这样来自特定 Hangfire 作业的所有日志都将具有相同的TrackingId我可以过滤。

我像这样配置 SerilogStartup.cs:

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每份 Hangfire 工作。我有什么办法可以实现这一目标吗?


对于它的价值,我最终使用服务器/客户端过滤器来完成这个任务,并且GlobalJobFilters注册如下所示。我遇到的一个恼人的问题是AutomaticRetryAttribute默认添加到GlobalJobFilters集合,以及该类将记录失败作业的错误 https://github.com/HangfireIO/Hangfire/blob/master/src/Hangfire.Core/AutomaticRetryAttribute.cs#L169不知道在我们自定义中创建的 Serilog LogContextJobLoggerAttribute。就我个人而言,我知道我只允许手动重试,因此我只是删除了该属性并在IServerFilter.OnPerformed方法。检查我的帖子的末尾,看看如何删除它(如果这对您有用)。

如果您要允许自动重试,那么您将需要:1)创建一个自定义属性来装饰AutomaticRetryAttribute并使其了解自定义 LogContext,2) 再次删除默认值AutomaticRetryAttribute来自GlobalJobFilters集合,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);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

丰富 Serlilogs,为每个 Hangfire 作业提供独特的价值 的相关文章

随机推荐