Skip to content

Commit

Permalink
[Instrumenation.Hangfire] File scoped namespace (open-telemetry#574)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kielek authored Aug 10, 2022
1 parent f9fcaaa commit b2b6c4b
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 202 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,31 @@
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Instrumentation.Hangfire.Implementation
{
using System;
using System.Diagnostics;
using System.Reflection;
namespace OpenTelemetry.Instrumentation.Hangfire.Implementation;

using System;
using System.Diagnostics;
using System.Reflection;

internal static class HangfireInstrumentation
{
/// <summary>
/// The assembly name.
/// </summary>
internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName();
internal static class HangfireInstrumentation
{
/// <summary>
/// The assembly name.
/// </summary>
internal static readonly AssemblyName AssemblyName = typeof(HangfireInstrumentation).Assembly.GetName();

/// <summary>
/// The activity source name.
/// </summary>
internal static readonly string ActivitySourceName = AssemblyName.Name;
/// <summary>
/// The activity source name.
/// </summary>
internal static readonly string ActivitySourceName = AssemblyName.Name;

/// <summary>
/// The version.
/// </summary>
internal static readonly Version Version = AssemblyName.Version;
/// <summary>
/// The version.
/// </summary>
internal static readonly Version Version = AssemblyName.Version;

/// <summary>
/// The activity source.
/// </summary>
internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString());
}
/// <summary>
/// The activity source.
/// </summary>
internal static readonly ActivitySource ActivitySource = new(ActivitySourceName, Version.ToString());
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,14 @@
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Instrumentation.Hangfire.Implementation
namespace OpenTelemetry.Instrumentation.Hangfire.Implementation;

internal static class HangfireInstrumentationConstants
{
internal static class HangfireInstrumentationConstants
{
public const string JobIdTag = "job.id";
public const string JobCreatedAtTag = "job.createdat";
public const string JobIdTag = "job.id";
public const string JobCreatedAtTag = "job.createdat";

public const string ActivityName = "JOB";
public const string ActivityKey = "opentelemetry_activity_key";
public const string ActivityContextKey = "opentelemetry_activity_context";
}
public const string ActivityName = "JOB";
public const string ActivityKey = "opentelemetry_activity_key";
public const string ActivityContextKey = "opentelemetry_activity_context";
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,102 +14,101 @@
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Instrumentation.Hangfire.Implementation
namespace OpenTelemetry.Instrumentation.Hangfire.Implementation;

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using global::Hangfire.Client;
using global::Hangfire.Common;
using global::Hangfire.Server;
using OpenTelemetry.Context.Propagation;

internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using global::Hangfire.Client;
using global::Hangfire.Common;
using global::Hangfire.Server;
using OpenTelemetry.Context.Propagation;

internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter
public void OnPerforming(PerformingContext performingContext)
{
public void OnPerforming(PerformingContext performingContext)
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners())
{
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners())
{
return;
}

var activityContextData = performingContext.GetJobParameter<Dictionary<string, string>>(HangfireInstrumentationConstants.ActivityContextKey);
ActivityContext parentContext = default;
if (activityContextData is not null)
{
var propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, activityContextData, ExtractActivityProperties);
parentContext = propagationContext.ActivityContext;
Baggage.Current = propagationContext.Baggage;
}

var activity = HangfireInstrumentation.ActivitySource
.StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext);

if (activity != null)
{
activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}";

if (activity.IsAllDataRequested)
{
activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id);
activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O"));
}
return;
}

performingContext.Items.Add(HangfireInstrumentationConstants.ActivityKey, activity);
}
var activityContextData = performingContext.GetJobParameter<Dictionary<string, string>>(HangfireInstrumentationConstants.ActivityContextKey);
ActivityContext parentContext = default;
if (activityContextData is not null)
{
var propagationContext = Propagators.DefaultTextMapPropagator.Extract(default, activityContextData, ExtractActivityProperties);
parentContext = propagationContext.ActivityContext;
Baggage.Current = propagationContext.Baggage;
}

public void OnPerformed(PerformedContext performedContext)
var activity = HangfireInstrumentation.ActivitySource
.StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext);

if (activity != null)
{
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey))
{
return;
}
activity.DisplayName = $"JOB {performingContext.BackgroundJob.Job.Type.Name}.{performingContext.BackgroundJob.Job.Method.Name}";

if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity)
if (activity.IsAllDataRequested)
{
if (performedContext.Exception != null)
{
activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message);
}

activity.Dispose();
activity.SetTag(HangfireInstrumentationConstants.JobIdTag, performingContext.BackgroundJob.Id);
activity.SetTag(HangfireInstrumentationConstants.JobCreatedAtTag, performingContext.BackgroundJob.CreatedAt.ToString("O"));
}

performingContext.Items.Add(HangfireInstrumentationConstants.ActivityKey, activity);
}
}

public void OnCreating(CreatingContext creatingContext)
public void OnPerformed(PerformedContext performedContext)
{
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners() || !performedContext.Items.ContainsKey(HangfireInstrumentationConstants.ActivityKey))
{
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners())
{
return;
}
return;
}

ActivityContext contextToInject = default;
if (Activity.Current != null)
if (performedContext.Items[HangfireInstrumentationConstants.ActivityKey] is Activity activity)
{
if (performedContext.Exception != null)
{
contextToInject = Activity.Current.Context;
activity.SetStatus(ActivityStatusCode.Error, performedContext.Exception.Message);
}

var activityContextData = new Dictionary<string, string>();
Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(contextToInject, Baggage.Current), activityContextData, InjectActivityProperties);
creatingContext.SetJobParameter(HangfireInstrumentationConstants.ActivityContextKey, activityContextData);
activity.Dispose();
}
}

public void OnCreated(CreatedContext filterContext)
public void OnCreating(CreatingContext creatingContext)
{
// Short-circuit if nobody is listening
if (!HangfireInstrumentation.ActivitySource.HasListeners())
{
return;
}

private static void InjectActivityProperties(IDictionary<string, string> jobParams, string key, string value)
ActivityContext contextToInject = default;
if (Activity.Current != null)
{
jobParams[key] = value;
contextToInject = Activity.Current.Context;
}

private static IEnumerable<string> ExtractActivityProperties(Dictionary<string, string> telemetryData, string key)
{
return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty<string>();
}
var activityContextData = new Dictionary<string, string>();
Propagators.DefaultTextMapPropagator.Inject(new PropagationContext(contextToInject, Baggage.Current), activityContextData, InjectActivityProperties);
creatingContext.SetJobParameter(HangfireInstrumentationConstants.ActivityContextKey, activityContextData);
}

public void OnCreated(CreatedContext filterContext)
{
}

private static void InjectActivityProperties(IDictionary<string, string> jobParams, string key, string value)
{
jobParams[key] = value;
}

private static IEnumerable<string> ExtractActivityProperties(Dictionary<string, string> telemetryData, string key)
{
return telemetryData.ContainsKey(key) ? new[] { telemetryData[key] } : Enumerable.Empty<string>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,27 @@
// limitations under the License.
// </copyright>

namespace OpenTelemetry.Trace
{
using OpenTelemetry.Instrumentation.Hangfire.Implementation;
using OpenTelemetry.Internal;
namespace OpenTelemetry.Trace;

using OpenTelemetry.Instrumentation.Hangfire.Implementation;
using OpenTelemetry.Internal;

/// <summary>
/// Extension methods to simplify registering of Hangfire job instrumentation.
/// </summary>
public static class TracerProviderBuilderExtensions
{
/// <summary>
/// Extension methods to simplify registering of Hangfire job instrumentation.
/// Adds Hangfire instrumentation to the tracer provider.
/// </summary>
public static class TracerProviderBuilderExtensions
/// <param name="builder"><see cref="TracerProviderBuilder"/> being configured.</param>
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder)
{
/// <summary>
/// Adds Hangfire instrumentation to the tracer provider.
/// </summary>
/// <param name="builder"><see cref="TracerProviderBuilder"/> being configured.</param>
/// <returns>The instance of <see cref="TracerProviderBuilder"/> to chain the calls.</returns>
public static TracerProviderBuilder AddHangfireInstrumentation(this TracerProviderBuilder builder)
{
Guard.ThrowIfNull(builder);
Guard.ThrowIfNull(builder);

Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute());
Hangfire.GlobalJobFilters.Filters.Add(new HangfireInstrumentationJobFilterAttribute());

return builder.AddSource(HangfireInstrumentation.ActivitySourceName);
}
return builder.AddSource(HangfireInstrumentation.ActivitySourceName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,24 @@
using Hangfire.MemoryStorage;
using Hangfire.Storage;

namespace OpenTelemetry.Instrumentation.Hangfire.Tests
namespace OpenTelemetry.Instrumentation.Hangfire.Tests;

public class HangfireFixture : IDisposable
{
public class HangfireFixture : IDisposable
public HangfireFixture()
{
public HangfireFixture()
{
GlobalConfiguration.Configuration
.UseMemoryStorage();
this.Server = new BackgroundJobServer();
this.MonitoringApi = JobStorage.Current.GetMonitoringApi();
}
GlobalConfiguration.Configuration
.UseMemoryStorage();
this.Server = new BackgroundJobServer();
this.MonitoringApi = JobStorage.Current.GetMonitoringApi();
}

public BackgroundJobServer Server { get; }
public BackgroundJobServer Server { get; }

public IMonitoringApi MonitoringApi { get; }
public IMonitoringApi MonitoringApi { get; }

public void Dispose()
{
this.Server.Dispose();
}
public void Dispose()
{
this.Server.Dispose();
}
}
Loading

0 comments on commit b2b6c4b

Please sign in to comment.