用每个 hangfire 作业的独特价值丰富 Serlilogs [英] Enrich Serlilogs with unique value per hangfire job

查看:30
本文介绍了用每个 hangfire 作业的独特价值丰富 Serlilogs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Hangfire 进行后台作业,使用 Serilog 进行日志记录.我正在尝试使用 TrackingId 来丰富我的 serilog,以便来自特定 Hangfire 作业的所有日志都具有相同的 TrackingId,我可以对其进行过滤.

I'm using Hangfire for background jobs, and Serilog for logging. I'm trying to enrich my serilogs with a TrackingId so that all logs from a specific Hangfire job will have the same TrackingId that I can filter on.

我在 Startup.cs 中这样配置 Serilog:

I configure Serilog like this in Startup.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));

但是这样做不会为每个 Hangfire 作业设置单独的 TrackingId.有什么办法可以实现吗?

But doing like this will not set a separate TrackingId per Hangfire job. Is there any way I can achieve that?

推荐答案

就其价值而言,我最终使用如下所示的服务器/客户端过滤器和 GlobalJobFilters 注册解决了这个问题.我遇到的一个烦人的问题是 AutomaticRetryAttribute 默认添加到 GlobalJobFilters 集合中,并且该类 将记录失败作业的错误,而无需了解在我们的自定义 JobLoggerAttribute 中创建的 Serilog LogContext.就我个人而言,我知道我只允许手动重试,所以我只是删除了该属性并在 IServerFilter.OnPerformed 方法中处理了错误.如果对您有用,请查看我帖子的末尾以了解如何将其删除.

For what it's worth, I ended up pulling this off using the server/client filter and GlobalJobFilters registration shown below. One annoying issue I ran into is that the AutomaticRetryAttribute is added by default to the GlobalJobFilters collection, and that class will log errors for failed jobs without knowledge of the Serilog LogContext created in our custom JobLoggerAttribute. Personally, I know I will only allow manual retry, so I just removed that attribute and handled the error within the IServerFilter.OnPerformed method. Check the end of my post to see how to remove it if that works for you.

如果您要允许自动重试,则需要:1) 创建一个自定义属性来修饰 AutomaticRetryAttribute 并使其知道自定义 LogContext,2) 再次删除默认值AutomaticRetryAttribute 来自 GlobalJobFilters 集合,以及 3) 将您的装饰器属性添加到集合中.

If you are going to allow automatic retry, then you will need to: 1) create a custom attribute that decorates the AutomaticRetryAttribute and makes it aware of a custom LogContext, 2) again remove the default AutomaticRetryAttribute from the GlobalJobFilters collection, and 3) add your decorator attribute to the collection.

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);

这篇关于用每个 hangfire 作业的独特价值丰富 Serlilogs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆