HangfireIO / Hangfire

An easy way to perform background job processing in .NET and .NET Core applications. No Windows Service or separate process required
https://www.hangfire.io
Other
9.4k stars 1.7k forks source link

Integration with New Relic for APM and error aggregation #1501

Open antgel opened 5 years ago

antgel commented 5 years ago

Hi Hangfire team,

@Jenia-Finkler and I have noticed that New Relic .NET Agent doesn't track Hangfire transactions. This causes us pain in production, because without APM and error tracking from Hangfire transactions, we're flying blind. I note from your docs that the Pro version has performance counters available, but I don't think that's what we're looking for - that will just help us see how many jobs are running.

How can this integration be made to work?

ghost commented 4 years ago

@antgel did you ever figure out a way to successfully instrument hangfire for new relic monitoring?

antgel commented 4 years ago

@msdos621 Unfortunately not, there are other priorities right now. Shame nobody from the Hangfire team acknowledged this issue in the 11 months it's been open. :man_shrugging: Would love to hear from anyone who gets the two playing nicely together.

ghost commented 4 years ago

@antgel I was able to sort of track hangfire stuff. I have my background / recurring task inheriting from a common base class that contains the Run method I attributed with the NewRelic transaction attribute from the NewRelic API like so

       [Transaction]
        public async Task<ScheduledTaskResult> Run(int taskId)
        {
            NewRelic.Api.Agent.NewRelic.SetTransactionName("Tasks", TaskName);
            NewRelicTransaction()?.AddCustomAttribute("TaskName", TaskName);
            NewRelicTransaction()?.AddCustomAttribute("TaskId", taskId);

           try {
                //Execute task is defined in the child classes for each task
                taskResult = await ExecuteTask();
            }
            catch (Exception ex)
            {
                  NewRelic.Api.Agent.NewRelic.NoticeError(ex);
            }
            return taskResult;
        }
nicumaxian commented 3 years ago

@antgel I was able to sort of track hangfire stuff. I have my background / recurring task inheriting from a common base class that contains the Run method I attributed with the NewRelic transaction attribute from the NewRelic API like so

       [Transaction]
        public async Task<ScheduledTaskResult> Run(int taskId)
        {
            NewRelic.Api.Agent.NewRelic.SetTransactionName("Tasks", TaskName);
            NewRelicTransaction()?.AddCustomAttribute("TaskName", TaskName);
            NewRelicTransaction()?.AddCustomAttribute("TaskId", taskId);

           try {
                //Execute task is defined in the child classes for each task
                taskResult = await ExecuteTask();
            }
            catch (Exception ex)
            {
                  NewRelic.Api.Agent.NewRelic.NoticeError(ex);
            }
            return taskResult;
        }

how about enqueued jobs which can take different set of arguments?

btw, you can NoticeError by using JobFilters

miguelgimenez commented 1 year ago

Hi,

In case anyone is still interested we managed to have tasks tracked in new relic using this JobFilter:

using Hangfire.Common;
using Hangfire.Server;
using NewRelic.Api.Agent;

namespace Nop.Plugin.AgileCommerce.Core.Hangfire
{
    public class NewRelicInstrumentationFilter : JobFilterAttribute, IServerFilter, IServerExceptionFilter
    {
        public void OnPerformed(PerformedContext filterContext)
        {
        }

        [Transaction]
        public void OnPerforming(PerformingContext filterContext)
        {
            NewRelic.Api.Agent.NewRelic.SetTransactionName("Hangfire", 
                $"{filterContext.BackgroundJob.Job.Type.Name}.{filterContext.BackgroundJob.Job.Method.Name}");
            var agent = NewRelic.Api.Agent.NewRelic.GetAgent();
            var transaction = agent.CurrentTransaction;
            transaction.AddCustomAttribute("jobId", filterContext.BackgroundJob.Id);
        }

        public void OnServerException(ServerExceptionContext filterContext)
        {
            NewRelic.Api.Agent.NewRelic.NoticeError(filterContext.Exception);
        }
    }
}
AnhQuanTrl commented 1 month ago

Using JobFilter will not work because the transaction tracing will not show any external calls made during the execution of the job. Errors inbox will work but it is not enough.