Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow parent/child relationship in Opentelemetry spans #1779

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
~static OpenTelemetry.Trace.OpenTelemetryExtensions.AddRabbitMQInstrumentation(this OpenTelemetry.Trace.TracerProviderBuilder builder, System.Action<RabbitMQ.Client.RabbitMQTracingOptions> configure) -> OpenTelemetry.Trace.TracerProviderBuilder
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,26 @@

namespace OpenTelemetry.Trace
{

public static class OpenTelemetryExtensions
{
public static TracerProviderBuilder AddRabbitMQInstrumentation(this TracerProviderBuilder builder)
public static TracerProviderBuilder AddRabbitMQInstrumentation(this TracerProviderBuilder builder, Action<RabbitMQTracingOptions> configure)
{
var options = new RabbitMQTracingOptions();
configure?.Invoke(options);
RabbitMQActivitySource.TracingOptions = options;

RabbitMQActivitySource.ContextExtractor = OpenTelemetryContextExtractor;
RabbitMQActivitySource.ContextInjector = OpenTelemetryContextInjector;
builder.AddSource("RabbitMQ.Client.*");
return builder;
}

public static TracerProviderBuilder AddRabbitMQInstrumentation(this TracerProviderBuilder builder)
{
return AddRabbitMQInstrumentation(builder, null);
}

private static ActivityContext OpenTelemetryContextExtractor(IReadOnlyBasicProperties props)
{
// Extract the PropagationContext of the upstream parent from the message headers.
Expand Down
32 changes: 26 additions & 6 deletions projects/RabbitMQ.Client/Impl/RabbitMQActivitySource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ public static class RabbitMQActivitySource
public static Func<IReadOnlyBasicProperties, ActivityContext> ContextExtractor { get; set; } =
DefaultContextExtractor;

public static bool UseRoutingKeyAsOperationName { get; set; } = true;
public static bool UseRoutingKeyAsOperationName
{
get => TracingOptions.UseRoutingKeyAsOperationName;
set => TracingOptions.UseRoutingKeyAsOperationName = value;
}
public static RabbitMQTracingOptions TracingOptions { get; set; } = new RabbitMQTracingOptions();
internal static bool PublisherHasListeners => s_publisherSource.HasListeners();

internal static readonly IEnumerable<KeyValuePair<string, object?>> CreationTags = new[]
Expand Down Expand Up @@ -115,9 +120,15 @@ public static class RabbitMQActivitySource
}

// Extract the PropagationContext of the upstream parent from the message headers.
ActivityContext linkedContext = ContextExtractor(readOnlyBasicProperties);
ActivityContext parentContext = TracingOptions.LinkType == TracingLinkType.AlwaysParentChildAndLink
? linkedContext : default;

Activity? activity = s_subscriberSource.StartLinkedRabbitMQActivity(
UseRoutingKeyAsOperationName ? $"{MessagingOperationNameBasicGet} {routingKey}" : MessagingOperationNameBasicGet, ActivityKind.Consumer,
ContextExtractor(readOnlyBasicProperties));
linkedContext, parentContext);


if (activity != null && activity.IsAllDataRequested)
{
PopulateMessagingTags(MessagingOperationTypeReceive, MessagingOperationNameBasicGet, routingKey, exchange, deliveryTag, readOnlyBasicProperties,
Expand All @@ -128,21 +139,25 @@ public static class RabbitMQActivitySource
}

internal static Activity? Deliver(string routingKey, string exchange, ulong deliveryTag,
IReadOnlyBasicProperties basicProperties, int bodySize)
IReadOnlyBasicProperties readOnlyBasicProperties, int bodySize)
{
if (!s_subscriberSource.HasListeners())
{
return null;
}

// Extract the PropagationContext of the upstream parent from the message headers.
ActivityContext linkedContext = ContextExtractor(readOnlyBasicProperties);
ActivityContext parentContext = TracingOptions.LinkType == TracingLinkType.AlwaysParentChildAndLink
? linkedContext : default;

Activity? activity = s_subscriberSource.StartLinkedRabbitMQActivity(
UseRoutingKeyAsOperationName ? $"{MessagingOperationNameBasicDeliver} {routingKey}" : MessagingOperationNameBasicDeliver,
ActivityKind.Consumer, ContextExtractor(basicProperties));
ActivityKind.Consumer, linkedContext, parentContext);
if (activity != null && activity.IsAllDataRequested)
{
PopulateMessagingTags(MessagingOperationTypeProcess, MessagingOperationNameBasicDeliver, routingKey, exchange,
deliveryTag, basicProperties, bodySize, activity);
deliveryTag, readOnlyBasicProperties, bodySize, activity);
}

return activity;
Expand All @@ -157,8 +172,13 @@ public static class RabbitMQActivitySource
private static Activity? StartLinkedRabbitMQActivity(this ActivitySource source, string name, ActivityKind kind,
ActivityContext linkedContext = default, ActivityContext parentContext = default)
{
var links = new List<ActivityLink>();
if (linkedContext != default)
{
links.Add(new ActivityLink(linkedContext));
}
meum marked this conversation as resolved.
Show resolved Hide resolved
return source.CreateActivity(name, kind, parentContext: parentContext,
links: new[] { new ActivityLink(linkedContext) }, idFormat: ActivityIdFormat.W3C,
links: links, idFormat: ActivityIdFormat.W3C,
tags: CreationTags)
?.Start();
}
Expand Down
14 changes: 14 additions & 0 deletions projects/RabbitMQ.Client/Impl/RabbitMQTracingOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace RabbitMQ.Client
{
public enum TracingLinkType
{
AlwaysLink,
AlwaysParentChildAndLink
}

public class RabbitMQTracingOptions
{
public bool UseRoutingKeyAsOperationName { get; set; } = true;
public TracingLinkType LinkType { get; set; } = TracingLinkType.AlwaysLink;
}
}
11 changes: 11 additions & 0 deletions projects/RabbitMQ.Client/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
RabbitMQ.Client.RabbitMQTracingOptions
RabbitMQ.Client.RabbitMQTracingOptions.LinkType.get -> RabbitMQ.Client.TracingLinkType
RabbitMQ.Client.RabbitMQTracingOptions.LinkType.set -> void
RabbitMQ.Client.RabbitMQTracingOptions.RabbitMQTracingOptions() -> void
RabbitMQ.Client.RabbitMQTracingOptions.UseRoutingKeyAsOperationName.get -> bool
RabbitMQ.Client.RabbitMQTracingOptions.UseRoutingKeyAsOperationName.set -> void
RabbitMQ.Client.TracingLinkType
RabbitMQ.Client.TracingLinkType.AlwaysLink = 0 -> RabbitMQ.Client.TracingLinkType
RabbitMQ.Client.TracingLinkType.AlwaysParentChildAndLink = 1 -> RabbitMQ.Client.TracingLinkType
static RabbitMQ.Client.RabbitMQActivitySource.TracingOptions.get -> RabbitMQ.Client.RabbitMQTracingOptions!
static RabbitMQ.Client.RabbitMQActivitySource.TracingOptions.set -> void
Loading