Skip to content

Commit

Permalink
[Instrumenation.Hangfire] Add options support to hangfire instrumenta…
Browse files Browse the repository at this point in the history
…tion (#1442)
  • Loading branch information
gao-artur authored Dec 5, 2023
1 parent 17264f0 commit cfebb97
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.get -> bool
OpenTelemetry.Trace.HangfireInstrumentationOptions.RecordException.set -> void
OpenTelemetry.Trace.TracerProviderBuilderExtensions
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder) -> OpenTelemetry.Trace.TracerProviderBuilder!
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, string? name, System.Action<OpenTelemetry.Trace.HangfireInstrumentationOptions!>? configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
static OpenTelemetry.Trace.TracerProviderBuilderExtensions.AddHangfireInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder! builder, System.Action<OpenTelemetry.Trace.HangfireInstrumentationOptions!>? configure) -> OpenTelemetry.Trace.TracerProviderBuilder!
5 changes: 5 additions & 0 deletions src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
* Update OTel API version to `1.6.0`.
([#1344](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1344))

* Added overloads which accept a name to the `TracerProviderBuilder`
`HangfireInstrumentationOptions` extension to allow for more fine-grained
options management
([#1442](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/1442))

## 1.5.0-beta.1

Released 2023-Jun-23
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@
// limitations under the License.
// </copyright>

using Hangfire;

namespace OpenTelemetry.Instrumentation.Hangfire.Implementation;

using System;
using System.Diagnostics;
using System.Reflection;
using Hangfire;
using OpenTelemetry.Trace;

namespace OpenTelemetry.Instrumentation.Hangfire.Implementation;

internal static class HangfireInstrumentation
internal sealed class HangfireInstrumentation
{
/// <summary>
/// The assembly name.
Expand All @@ -49,4 +49,9 @@ internal static class HangfireInstrumentation
/// </summary>
internal static readonly Func<BackgroundJob, string> DefaultDisplayNameFunc =
backgroundJob => $"JOB {backgroundJob.Job.Type.Name}.{backgroundJob.Job.Method.Name}";

public HangfireInstrumentation(HangfireInstrumentationOptions options)
{
GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Hangfire.Core" Version="[1.7.0,1.9.0)" />
<PackageReference Include="OpenTelemetry.Api" Version="$(OpenTelemetryCoreLatestVersion)" />
<PackageReference Include="Microsoft.Extensions.Options" Version="$(MicrosoftExtensionsOptionsPkgVer)" />
<PackageReference Include="OpenTelemetry.Api.ProviderBuilderExtensions" Version="$(OpenTelemetryCoreLatestVersion)" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(RepoRoot)\src\Shared\Guard.cs" Link="Includes\Guard.cs" />
Expand Down
23 changes: 23 additions & 0 deletions src/OpenTelemetry.Instrumentation.Hangfire/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,29 @@ the `ConfigureServices` of your `Startup` class. Refer to [example](https://gith
For an ASP.NET application, adding instrumentation is typically done in the
`Global.asax.cs`. Refer to [example](../../examples/AspNet/Global.asax.cs).

## Advanced configuration

When used with
[`OpenTelemetry.Extensions.Hosting`](https://github.com/open-telemetry/opentelemetry-dotnet/blob/main/src/OpenTelemetry.Extensions.Hosting/README.md),
all configurations to `HangfireInstrumentationOptions`
can be done in the `ConfigureServices` method of your applications `Startup`
class as shown below.

```csharp
// 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());
```

## References

* [OpenTelemetry Project](https://opentelemetry.io/)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Trace;

using System;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenTelemetry.Instrumentation.Hangfire.Implementation;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Trace;

/// <summary>
/// Extension methods to simplify registering of Hangfire job instrumentation.
/// </summary>
Expand All @@ -32,7 +34,7 @@ public static class TracerProviderBuilderExtensions
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder AddHangfireInstrumentation(
this TracerProviderBuilder builder) =>
AddHangfireInstrumentation(builder, configure: null);
AddHangfireInstrumentation(builder, name: null, configure: null);

/// <summary>
/// Adds Hangfire instrumentation to the tracer provider.
Expand All @@ -42,14 +44,35 @@ public static TracerProviderBuilder AddHangfireInstrumentation(
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder AddHangfireInstrumentation(
this TracerProviderBuilder builder,
Action<HangfireInstrumentationOptions>? configure) =>
AddHangfireInstrumentation(builder, name: null, configure);

/// <summary>
/// Adds Hangfire instrumentation to the tracer provider.
/// </summary>
/// <param name="builder"><see cref="TracerProviderBuilder"/> being configured.</param>
/// <param name="name">Name which is used when retrieving options.</param>
/// <param name="configure"><see cref="HangfireInstrumentationOptions"/> configuration options.</param>
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder AddHangfireInstrumentation(
this TracerProviderBuilder builder,
string? name,
Action<HangfireInstrumentationOptions>? configure)
{
Guard.ThrowIfNull(builder);

var options = new HangfireInstrumentationOptions();
configure?.Invoke(options);
name ??= Options.DefaultName;

if (configure != null)
{
builder.ConfigureServices(services => services.Configure(name, configure));
}

Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute(options));
builder.AddInstrumentation(sp =>
{
var options = sp.GetRequiredService<IOptionsMonitor<HangfireInstrumentationOptions>>().Get(name);
return new HangfireInstrumentation(options);
});

return builder.AddSource(HangfireInstrumentation.ActivitySourceName);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// <copyright file="DependencyInjectionConfigTests.cs" company="OpenTelemetry Authors">
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// </copyright>

using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using OpenTelemetry.Trace;
using Xunit;

namespace OpenTelemetry.Instrumentation.Hangfire.Tests;

public class DependencyInjectionConfigTests
{
[Theory]
[InlineData(null)]
[InlineData("CustomName")]
public async Task TestTracingOptionsDiConfig(string name)
{
bool optionsPickedFromDi = false;

var services = new ServiceCollection();

services
.Configure<HangfireInstrumentationOptions>(name, _ => optionsPickedFromDi = true)
.AddOpenTelemetry()
.WithTracing(builder =>
builder.AddHangfireInstrumentation(name, configure: null));

var sp = services.BuildServiceProvider();

try
{
foreach (var hostedService in sp.GetServices<IHostedService>())
{
await hostedService.StartAsync(CancellationToken.None);
}

Assert.True(optionsPickedFromDi);
}
finally
{
foreach (var hostedService in sp.GetServices<IHostedService>().Reverse())
{
await hostedService.StopAsync(CancellationToken.None);
}

await sp.DisposeAsync();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<PackageReference Include="Hangfire.Core" Version="1.8.1" />
<PackageReference Include="Hangfire.MemoryStorage" Version="1.7.0" />
<PackageReference Include="OpenTelemetry.Exporter.InMemory" Version="$(OpenTelemetryExporterInMemoryPkgVer)" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="$(OpenTelemetryCoreLatestVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="$(RepoRoot)\src\OpenTelemetry.Instrumentation.Hangfire\OpenTelemetry.Instrumentation.Hangfire.csproj" />
Expand Down

0 comments on commit cfebb97

Please sign in to comment.