Build status NuGet Samples

Logging heartbeats from Hangfire

The Heartbeats feature is currently in beta and still experimental.

Scheduling recurring tasks with Hangfire is easy. Monitoring if tasks successfully execute or even run can be a challenge. With elmah.io Heartbeats we provide native monitoring of Hangfire recurring taks.

To publish heartbeats from Hangifre, install the Elmah.Io.Heartbeats.Hangfire NuGet package:

Install-Package Elmah.Io.Heartbeats.Hangfire -IncludePrerelease

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 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()
{
    ...
}

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