Skip to content

Commit

Permalink
[Hangfire OTEL] create parent context if traceparent is available (#421)
Browse files Browse the repository at this point in the history
* create parent context if traceparent is available
  • Loading branch information
marcindruzgala authored Jul 12, 2022
1 parent 6e84090 commit f27d824
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/OpenTelemetry.Instrumentation.Hangfire/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

* Added client side instrumentation for jobs ([#421](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/421))

## 1.0.0-beta.1

* Updated OTel SDK package version to 1.2.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ internal static class HangfireInstrumentationConstants

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 @@ -16,11 +16,15 @@

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
internal class HangfireInstrumentationJobFilterAttribute : JobFilterAttribute, IServerFilter, IClientFilter
{
public void OnPerforming(PerformingContext performingContext)
{
Expand All @@ -30,8 +34,17 @@ public void OnPerforming(PerformingContext performingContext)
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: default);
.StartActivity(HangfireInstrumentationConstants.ActivityName, ActivityKind.Internal, parentContext);

if (activity != null)
{
Expand Down Expand Up @@ -65,5 +78,38 @@ public void OnPerformed(PerformedContext performedContext)
activity.Dispose();
}
}

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

ActivityContext contextToInject = default;
if (Activity.Current != null)
{
contextToInject = Activity.Current.Context;
}

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>();
}
}
}

0 comments on commit f27d824

Please sign in to comment.