![]() |
VOOZH | about |
dotnet add package OpenTelemetry.Instrumentation.Hangfire --version 1.15.1-beta.1
NuGet\Install-Package OpenTelemetry.Instrumentation.Hangfire -Version 1.15.1-beta.1
<PackageReference Include="OpenTelemetry.Instrumentation.Hangfire" Version="1.15.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Hangfire" Version="1.15.1-beta.1" />Directory.Packages.props
<PackageReference Include="OpenTelemetry.Instrumentation.Hangfire" />Project file
paket add OpenTelemetry.Instrumentation.Hangfire --version 1.15.1-beta.1
#r "nuget: OpenTelemetry.Instrumentation.Hangfire, 1.15.1-beta.1"
#:package OpenTelemetry.Instrumentation.Hangfire@1.15.1-beta.1
#addin nuget:?package=OpenTelemetry.Instrumentation.Hangfire&version=1.15.1-beta.1&prereleaseInstall as a Cake Addin
#tool nuget:?package=OpenTelemetry.Instrumentation.Hangfire&version=1.15.1-beta.1&prereleaseInstall as a Cake Tool
| Status | |
|---|---|
| Stability | Beta |
| Code Owners | @fred2u |
👁 NuGet version badge
👁 NuGet download count badge
👁 codecov.io
This is an Instrumentation Library, which instruments Hangfire and collects traces and metrics about BackgroundJob executions.
Please note that installing the OpenTelemetry Hangfire instrumentation will retrieve from NuGet and install Hangfire.Core, which is provided by its licensor under a choice of LGPL-3.0 or a commercial license.
The following steps show how to enable tracing. For metrics, see the Metrics section below.
Add a reference to the
OpenTelemetry.Instrumentation.Hangfire
package. Also, add any other instrumentations & exporters you will need.
dotnet add package OpenTelemetry.Instrumentation.Hangfire --prerelease
Hangfire instrumentation must be enabled at application startup.
The following example demonstrates adding Hangfire instrumentation to a
console application. This example also sets up the OpenTelemetry Console
exporter, which requires adding the package
OpenTelemetry.Exporter.Console
to the application.
using OpenTelemetry.Trace;
public class Program
{
public static void Main(string[] args)
{
using var tracerProvider = Sdk
.CreateTracerProviderBuilder()
.AddHangfireInstrumentation()
.AddConsoleExporter()
.Build();
}
}
For an ASP.NET Core application, adding instrumentation is typically done in
the ConfigureServices of your Startup class. Refer to example.
For an ASP.NET application, adding instrumentation is typically done in the
Global.asax.cs. Refer to example.
This instrumentation can be configured to change the default behavior by using
HangfireInstrumentationOptions.
using var tracerProvider = Sdk
.CreateTracerProviderBuilder()
.AddHangfireInstrumentation(options =>
{
options.DisplayNameFunc = job => $"JOB {job.Id}";
options.Filter = job => job.Id == "Filter this job";
options.RecordException = true;
})
.AddConsoleExporter()
.Build();
When used with
OpenTelemetry.Extensions.Hosting,
all configurations to HangfireInstrumentationOptions
can be done in the ConfigureServices method of your applications Startup
class as shown below.
// Configure
services.Configure<HangfireInstrumentationOptions>(options =>
{
options.DisplayNameFunc = job => $"JOB {job.Id}";
options.Filter = job => job.Id == "Filter this job";
options.RecordException = true;
});
services.AddOpenTelemetry()
.WithTracing(builder => builder
.AddHangfireInstrumentation()
.AddConsoleExporter());
Configures a value indicating whether the exception will be recorded as ActivityEvent or not. See Semantic Conventions for Exceptions on Spans
using var tracerProvider = Sdk
.CreateTracerProviderBuilder()
.AddHangfireInstrumentation(options =>
{
options.RecordException = true;
})
.AddConsoleExporter()
.Build();
This option allows changing activity display name.
using var tracerProvider = Sdk
.CreateTracerProviderBuilder()
.AddHangfireInstrumentation(options =>
{
options.DisplayNameFunc = job => $"JOB {job.Id}";
})
.AddConsoleExporter()
.Build();
If not configured the default is
$"JOB {BackgroundJob.Job.Type.Name}.{BackgroundJob.Job.Method.Name}"
This option can be used to filter out activities based on the BackgroundJob
being executed. The Filter function should return true if the telemetry is
to be collected, and false if it should not.
The following code snippet shows how to use Filter to filter out traces for
job with a specified job id.
using var tracerProvider = Sdk
.CreateTracerProviderBuilder()
.AddHangfireInstrumentation(options =>
{
options.Filter = job => job.Id == "Filter this job";
})
.AddConsoleExporter()
.Build();
This instrumentation library collects metrics following a POC/draft definition of workflow metrics defined as part of semantic-conventions/#1688. As those definitions evolve, changes including breaking ones will flow back to this implementation.
In Hangfire, the workflow semantic conventions are applied as follows:
This approach provides comprehensive visibility into both job creation/scheduling and actual execution performance.
Metrics are enabled by adding Hangfire instrumentation to the MeterProviderBuilder:
using OpenTelemetry.Metrics;
var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddHangfireInstrumentation()
.AddConsoleExporter()
.Build();
The above example also sets up the OpenTelemetry Console exporter, which requires
adding the package
OpenTelemetry.Exporter.Console
to the application.
To collect both traces and metrics from Hangfire:
using OpenTelemetry.Metrics;
using OpenTelemetry.Trace;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddOpenTelemetry()
.WithTracing(tracing => tracing
.AddHangfireInstrumentation()
.AddOtlpExporter())
.WithMetrics(metrics => metrics
.AddHangfireInstrumentation()
.AddOtlpExporter());
Metrics behavior is configured through the
HangfireMetricsInstrumentationOptions class in the
OpenTelemetry.Metrics namespace.
By default, the instrumentation records only the execution phase duration
(time spent actually running the job). To also track the pending phase
duration (time spent waiting in the queue before execution), enable the
RecordQueueLatency option:
var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddHangfireInstrumentation(options =>
{
options.RecordQueueLatency = true;
})
.AddConsoleExporter()
.Build();
When enabled, workflow.execution.duration is recorded with
workflow.execution.state="pending" representing queue wait time, in addition
to workflow.execution.state="executing" for actual execution time.
Enabling RecordQueueLatency requires an additional database query per job
execution to retrieve the enqueue timestamp. In high-throughput scenarios,
this may impact performance.
Add using OpenTelemetry.Metrics; to access
HangfireMetricsInstrumentationOptions.
The following metrics are emitted by this instrumentation:
Execution-level metrics track jobs that have entered the execution pipeline:
workflow.execution.outcome - Counter for completed executionsworkflow.execution.duration - Histogram for execution duration (pending
and executing phases)workflow.execution.status - UpDownCounter for current execution stateworkflow.execution.errors - Counter for execution errorsWorkflow-level metrics track the complete job lifecycle:
workflow.outcome - Counter for completed workflowsworkflow.status - UpDownCounter for current workflow state (including
scheduled jobs)The number of task executions which have been initiated.
| Units | Instrument Type | Value Type |
|---|---|---|
{executions} |
Counter | Int64 |
This metric does NOT include the workflow.execution.state attribute, as
state differentiation is not needed for counting completed executions.
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
workflow.task.name |
string | Name of the task (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.execution.result |
string | The result of executing the task | Required | success, failure |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
error.type |
string | The type of error that occurred | Conditionally Required[1] | Exception type name |
[1]: Required if and only if the task execution failed.
Duration of an execution grouped by task, state, and result. Records duration for different execution phases:
RecordQueueLatency is enabled)| Units | Instrument Type | Value Type |
|---|---|---|
s |
Histogram | Double |
The workflow.execution.state attribute is an extension to the current
semantic conventions to support measuring different execution phases
(pending vs executing). This attribute is being proposed for inclusion in
the official semantic conventions.
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
workflow.task.name |
string | Name of the task (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.execution.result |
string | The result of executing the task | Required | success, failure |
workflow.execution.state |
string | The execution phase being measured | Required | pending, executing |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
error.type |
string | The type of error that occurred | Conditionally Required[1] | Exception type name |
[1]: Required if and only if the task execution failed.
The number of actively running tasks grouped by task and the current state.
| Units | Instrument Type | Value Type |
|---|---|---|
{executions} |
UpDownCounter | Int64 |
This metric tracks the current state of job executions. When a job transitions to a new state, the previous state is decremented and the new state is incremented.
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
workflow.task.name |
string | Name of the task (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.execution.state |
string | Current state of the execution | Required | pending, executing, completed |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
error.type |
string | The type of error that occurred | Conditionally Required[1] | Exception type name |
[1]: Required if and only if the task execution failed.
Hangfire State Mapping:
Hangfire job states are mapped to workflow semantic convention states as follows:
| Hangfire State | Workflow State |
|---|---|
| Scheduled, Enqueued, Awaiting | pending |
| Processing | executing |
| Succeeded, Failed, Deleted | completed |
The number of errors encountered in task executions.
| Units | Instrument Type | Value Type |
|---|---|---|
{error} |
Counter | Int64 |
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
error.type |
string | The type of error that occurred | Required | Exception type name |
workflow.task.name |
string | Name of the task (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
The number of workflow instances which have been initiated. In Hangfire, this tracks individual job completions.
| Units | Instrument Type | Value Type |
|---|---|---|
{workflows} |
Counter | Int64 |
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
workflow.definition.name |
string | Name of the workflow (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.result |
string | The result of the workflow | Required | success, failure |
workflow.trigger.type |
string | Type of trigger that initiated the workflow | Required | api, cron, schedule |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
error.type |
string | The type of error that occurred | Conditionally Required[1] | Exception type name |
[1]: Required if and only if the workflow execution failed.
The number of actively running workflows grouped by definition and the current state.
| Units | Instrument Type | Value Type |
|---|---|---|
{workflows} |
UpDownCounter | Int64 |
This metric tracks the workflow lifecycle including jobs that haven't entered the execution pipeline yet (e.g., scheduled jobs waiting for their trigger time). When a workflow transitions to a new state, the previous state is decremented and the new state is incremented.
Attributes:
| Attribute | Type | Description | Requirement Level | Values |
|---|---|---|---|---|
workflow.definition.name |
string | Name of the workflow (Hangfire job method) | Required | e.g., MyJob.Execute |
workflow.state |
string | Current state of the workflow | Required | pending, executing, completed |
workflow.trigger.type |
string | Type of trigger that initiated the workflow | Required | api, cron, schedule |
workflow.platform.name |
string | The workflow platform being used | Recommended | hangfire |
error.type |
string | The type of error that occurred | Conditionally Required[1] | Exception type name |
[1]: Required if and only if the workflow execution failed.
Hangfire State Mapping:
Hangfire job states are mapped to workflow semantic convention states as follows:
| Hangfire State | Workflow State | Workflow Trigger Type |
|---|---|---|
| Scheduled | pending |
schedule |
| Enqueued, Awaiting (from cron) | pending |
cron |
| Enqueued, Awaiting (fire-and-forget) | pending |
api |
| Processing | executing |
(inherited from previous state) |
| Succeeded, Failed, Deleted | completed |
(inherited from previous state) |
Difference between workflow.status and workflow.execution.status:
workflow.status: Tracks the complete workflow lifecycle, including
jobs that haven't started execution yet (e.g., scheduled jobs waiting for
their trigger time). This provides visibility into jobs across all states.
workflow.execution.status: Tracks only jobs that have entered the
execution pipeline (enqueued or later). Scheduled jobs do NOT appear here
until they become enqueued.
For example, a scheduled job appears in
workflow.status{state=pending, trigger.type=schedule} but NOT in
workflow.execution.status until it becomes enqueued. Once enqueued, it
appears in both metrics.
This instrumentation follows the OpenTelemetry semantic conventions for workflows:
"hangfire"ClassName.MethodName)
workflow.task.name is used for execution-level metrics
(workflow.execution.*)workflow.definition.name is used for workflow-level metrics
(workflow.outcome, workflow.status)"cron" for recurring jobs"schedule" for delayed jobs (scheduled for future execution)"api" for fire-and-forget and continuation jobsworkflow.outcome,
workflow.status), not on execution-level metrics
(workflow.execution.*)"success" when
jobs complete without errors, "failure" when an exception is thrownworkflow.execution.state tracks execution pipeline states (used in
workflow.execution.status, workflow.execution.duration)workflow.state tracks complete workflow lifecycle (used in
workflow.status)The instrumentation distinguishes between workflow-level and execution-level metrics:
Workflow-level metrics (workflow.outcome, workflow.status):
workflow.definition.name, workflow.state, and
workflow.trigger.typeExecution-level metrics (workflow.execution.*):
workflow.task.name and workflow.execution.stateworkflow.trigger.type (trigger is a workflow-level concept)| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 5 NuGet packages that depend on OpenTelemetry.Instrumentation.Hangfire:
| Package | Downloads |
|---|---|
|
Grafana.OpenTelemetry
Full Grafana distribution of OpenTelemetry .NET |
|
|
Co.Backend.Packages.Presentation
Package Description |
|
|
Keed_Digital.SharedKernel.Infrastructure
Package Description |
|
|
CyberEye.Observability.Lib
Package cung cấp các cấu hình về Observability, Monitoring, Telemetry như Metrics, Traces |
|
|
Eaf.OpenTelemetry
Enterprise Application Foundation - OpenTelemetry implementation |
Showing the top 1 popular GitHub repositories that depend on OpenTelemetry.Instrumentation.Hangfire:
| Repository | Stars |
|---|---|
|
bitfoundation/bitplatform
Build all of your apps using what you already know and love ❤️
|
| Version | Downloads | Last Updated |
|---|---|---|
| 1.15.1-beta.1 | 251,722 | 4/21/2026 |
| 1.15.0-beta.1 | 497,247 | 1/21/2026 |
| 1.14.0-beta.2 | 78,530 | 1/14/2026 |
| 1.14.0-beta.1 | 173,671 | 11/13/2025 |
| 1.13.0-beta.1 | 79,880 | 10/23/2025 |
| 1.12.0-beta.1 | 909,833 | 6/23/2025 |
| 1.9.0-beta.1 | 2,057,151 | 10/2/2024 |
| 1.6.0-beta.1 | 3,013,983 | 12/20/2023 |
| 1.5.0-beta.1 | 1,056,770 | 6/23/2023 |
| 1.0.0-beta.4 | 960,709 | 12/16/2022 |
| 1.0.0-beta.3 | 114,105 | 10/26/2022 |
| 1.0.0-beta.2 | 295,902 | 7/13/2022 |
| 1.0.0-beta.1 | 23,520 | 6/3/2022 |