QueueHawk.Agent
1.1.0
See the version list below for details.
dotnet add package QueueHawk.Agent --version 1.1.0
NuGet\Install-Package QueueHawk.Agent -Version 1.1.0
<PackageReference Include="QueueHawk.Agent" Version="1.1.0" />
<PackageVersion Include="QueueHawk.Agent" Version="1.1.0" />
<PackageReference Include="QueueHawk.Agent" />
paket add QueueHawk.Agent --version 1.1.0
#r "nuget: QueueHawk.Agent, 1.1.0"
#:package QueueHawk.Agent@1.1.0
#addin nuget:?package=QueueHawk.Agent&version=1.1.0
#tool nuget:?package=QueueHawk.Agent&version=1.1.0
QueueHawk.Agent
The Hangfire dashboard you already have doesn't survive a restart, doesn't cover more than one app, and doesn't tell anyone when a job silently stops running. QueueHawk does.
QueueHawk.Agent is a lightweight NuGet package that plugs into your existing Hangfire setup and streams job history, failures, and worker heartbeats to QueueHawk â a hosted dashboard built for teams and agencies running Hangfire across multiple apps, clients, and environments.
- ð One dashboard for every app â stop tab-hopping between a dozen
/hangfiredashboards for a dozen client projects. - ð Persistent history â job history survives redeploys and restarts, unlike Hangfire's own dashboard.
- ð Real alerting â get a Slack, Teams, or email alert when error rates spike or a server stops sending heartbeats, instead of finding out when a client calls.
- ð Heartbeat monitoring â catches the scary case a pure job-event feed can't: a worker that's alive but has quietly stopped picking up jobs at all.
- ð Privacy by design â job arguments/payloads are never sent unless you explicitly opt in; only metadata (job type, queue, timing, state, exception details) leaves your infrastructure, and exception content itself can be redacted or dropped before it ever leaves the process via
OnBeforeSend. - ðĪ Push-only, one outbound hostname â the agent only ever makes outbound HTTPS calls; nothing needs to be opened inbound in your firewall.
- ðŠķ Negligible overhead â job state changes are captured via Hangfire's own filter pipeline and dropped onto an in-memory channel; a background service batches and ships them, so nothing in your job execution path waits on a network call.
- ðĄïļ Fails safe â the agent can never throw into your job pipeline. Every internal operation is exception-guarded; if QueueHawk is unreachable, jobs keep running and events buffer locally (oldest dropped first past 5,000 events) until it recovers.
Install
dotnet add package QueueHawk.Agent
Quick start
Get an API key by creating a free account and an application at queuehawk.com, then register the agent alongside your existing Hangfire setup:
builder.Services.AddHangfire(config => config.UseSqlServerStorage(connectionString));
builder.Services.AddHangfireServer();
// QueueHawk integration â one line, no changes to existing job code
builder.Services.AddQueueHawk(options =>
{
options.ApiKey = builder.Configuration["QueueHawk:ApiKey"];
options.Environment = "Production"; // free-text label, e.g. also useful as a client/tenant name
});
That's it â no Hangfire storage access required, no extra process to run. Job events and heartbeats start showing up in your QueueHawk dashboard within seconds.
Configuration
All options are optional except ApiKey:
| Option | Description | Default |
|---|---|---|
ApiKey |
Identifies your QueueHawk tenant/application | (required) |
Environment |
Free-text label shown in the dashboard (e.g. "Production", "Client XY - Staging") |
"Default" |
IncludeJobPayloads |
Also send job argument values (opt-in â off by default to avoid exfiltrating PII/business data) | false |
OnBeforeSend |
Callback invoked per event before it enters the local buffer â redact/mask fields or return null to drop the event entirely. See below. |
null |
MaxStackTraceLength |
Truncates long stack traces before sending | 4000 |
BatchIntervalSeconds |
How often buffered events are flushed | 5 |
HeartbeatIntervalSeconds |
How often each Hangfire server reports a heartbeat | 30 |
Enabled |
Global on/off switch (e.g. disable for local development) | true |
MaxBufferedEvents |
Local ring-buffer size (oldest dropped first once full) | 5000 |
IngestionBaseUrl |
Ingestion API hostname â override only for local testing/self-hosting | "https://ingest.queuehawk.com" |
Redacting sensitive exception content
Exception messages and stack traces are sent as-is by default (only truncated to MaxStackTraceLength) â job payloads are the thing that's off by default (IncludeJobPayloads), not exception text. If an exception message itself can contain PII (e.g. a validation error that echoes a customer's email address), use OnBeforeSend to redact or drop the event before it's ever buffered in memory:
builder.Services.AddQueueHawk(options =>
{
options.ApiKey = builder.Configuration["QueueHawk:ApiKey"];
options.Environment = "Production";
options.OnBeforeSend = jobEvent =>
{
if (jobEvent.ExceptionMessage is null)
{
return jobEvent;
}
return jobEvent with
{
ExceptionMessage = Regex.Replace(
jobEvent.ExceptionMessage,
@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
"[REDACTED-EMAIL]"),
};
};
});
The callback runs for every state-change event (not just failures), can return a rewritten JobEventDto, and returning null drops that event entirely â nothing is buffered or sent. Like every other agent operation, an exception thrown from your callback never propagates into your Hangfire job pipeline; that one event is simply dropped. Full option reference: queuehawk.com/docs/agent-configuration.
How it works
QueueHawk.Agent hooks into Hangfire's own IElectStateFilter/IApplyStateFilter extension points â the same mechanism Hangfire itself uses â so it sees every job state transition (Enqueued â Processing â Succeeded/Failed, including retries) without touching your job code or your Hangfire storage. Each event is written to a non-blocking in-memory channel; a background service batches and ships them over HTTPS. A second background service reports a periodic heartbeat per Hangfire server, which is how QueueHawk detects the failure mode a job-event stream alone can't: a server that's still running but has stopped processing anything at all.
Compatibility
- .NET: 8, 9, and 10
- Hangfire: works against any Hangfire storage backend (SQL Server, PostgreSQL, Redis, ...) â the agent only uses Hangfire's filter API, never talks to storage directly
Learn more
- queuehawk.com â sign up, pricing, and full product overview
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Hangfire.Core (>= 1.8.23)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
-
net8.0
- Hangfire.Core (>= 1.8.23)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
-
net9.0
- Hangfire.Core (>= 1.8.23)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.10)
- Microsoft.Extensions.Http (>= 10.0.10)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.10)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.