Logging heartbeats from Hangfire
Scheduling recurring tasks with Hangfire is easy. Monitoring if tasks are successfully executed or even run can be a challenge. With elmah.io Heartbeats, we provide native monitoring of Hangfire recurring tasks.
To publish heartbeats from Hangifre, install the Elmah.Io.Heartbeats.Hangfire
NuGet package:
Install-Package Elmah.Io.Heartbeats.Hangfire
dotnet add package Elmah.Io.Heartbeats.Hangfire
<PackageReference Include="Elmah.Io.Heartbeats.Hangfire" Version="5.*" />
paket add Elmah.Io.Heartbeats.Hangfire
For this example, we'll schedule a method named Test
to execute every minute:
RecurringJob.AddOrUpdate(() => Test(), Cron.Minutely);
To automatically publish a heartbeat when the job is executed, add the following using
:
using Elmah.Io.Heartbeats.Hangfire;
And decorate the Test
-method with the ElmahIoHeartbeat
attribute:
[ElmahIoHeartbeat("API_KEY", "LOG_ID", "HEARTBEAT_ID")]
public void Test()
{
// ...
}
Replace API_KEY
(Where is my API key?), LOG_ID
(Where is my log ID?), and HEARTBEAT_ID
with the correct variables from elmah.io.
When the job successfully runs, a Healthy
heartbeat is logged to elmah.io. If an exception is thrown an Unhealthy
heartbeat is logged. elmah.io will automatically create an error if a heartbeat is missing, as long as the heartbeat is correctly configured as explained in Set up Heartbeats.
Move configuration to config files
You normally don't include your API key, log ID, and heartbeat ID in C# code as shown in the example above. Unfortunately, Hangfire attributes doesn't support dependency injection or configuration from config files. There's a small "hack" that you can use to move the configuration to a configuration file by creating a custom attribute:
using Elmah.Io.Heartbeats.Hangfire;
using Hangfire.Common;
using Hangfire.Server;
using System.Configuration;
public class AppSettingsElmahIoHeartbeatAttribute : JobFilterAttribute, IServerFilter
{
private readonly ElmahIoHeartbeatAttribute _inner;
public AppSettingsElmahIoHeartbeatAttribute()
{
var apiKey = ConfigurationManager.AppSettings["apiKey"];
var logId = ConfigurationManager.AppSettings["logId"];
var heartbeatId = ConfigurationManager.AppSettings["heartbeatId"];
_inner = new ElmahIoHeartbeatAttribute(apiKey, logId, heartbeatId);
}
public void OnPerformed(PerformedContext filterContext)
{
_inner.OnPerformed(filterContext);
}
public void OnPerforming(PerformingContext filterContext)
{
_inner.OnPerforming(filterContext);
}
}
In the example the AppSettingsElmahIoHeartbeatAttribute
class wrap ElmahIoHeartbeatAttribute
. By doing so, it is possible to fetch configuration from application settings as part of the constructor. The approach would be similar when using IConfiguration
(like in ASP.NET Core), but you will need to share a reference to the configuration object somehow.
To use AppSettingsElmahIoHeartbeatAttribute
simply add it to the method:
[AppSettingsElmahIoHeartbeat]
public void Test()
{
// ...
}
As an alternative, you can register the ElmahIoHeartbeatAttribute
as a global attribute. In this example we use IConfiguration
in ASP.NET Core to fetch configuration from the appsettings.json
file:
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHangfire(config => config
// ...
.UseFilter(new ElmahIoHeartbeatAttribute(
Configuration["ElmahIo:ApiKey"],
Configuration["ElmahIo:LogId"],
Configuration["ElmahIo:HeartbeatId"])));
}
// ...
}
This will execute the ElmahIoHeartbeat
filter for every Hangfire job which isn't ideal if running multiple jobs within the same project.
This article was brought to you by the elmah.io team. elmah.io is the best error management system for .NET web applications. We monitor your website, alert you when errors start happening, and help you fix errors fast.
See how we can help you monitor your website for crashes Monitor your website