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

[Instrumentation.MassTransit] Masstransit enricher #696

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b6125c5
Add documentation to the manstransit README.md
nicolasderycke Oct 13, 2022
f533a3a
Revert "Add documentation to the manstransit README.md"
nicolasderycke Oct 14, 2022
adc6e51
Add documentation to the manstransit README.md
nicolasderycke Oct 13, 2022
0a5f8b6
Revert "Add documentation to the manstransit README.md"
nicolasderycke Oct 14, 2022
5dd5989
Merge branch 'main' of https://github.com/nicolasderycke/opentelemetr…
nicolasderycke Oct 14, 2022
10c293b
Add documentation to the manstransit README.md
nicolasderycke Oct 13, 2022
5892e05
Revert "Add documentation to the manstransit README.md"
nicolasderycke Oct 14, 2022
6fd006f
Merge branch 'main' of https://github.com/nicolasderycke/opentelemetr…
nicolasderycke Oct 14, 2022
0dc7398
Add masstransit enriching option and document in README.md
nicolasderycke Oct 14, 2022
9f15f7e
Update masstransit CHANGELOG.md with the enricher for Masstransit act…
nicolasderycke Oct 14, 2022
d6afb9b
Fix masstransit instrumentation tests
nicolasderycke Oct 17, 2022
c504f89
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Oct 17, 2022
ebbe180
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Oct 19, 2022
e515755
Pass the event name in the enrichment exception on OnStopActivity
nicolasderycke Oct 25, 2022
7aeb49a
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Oct 25, 2022
48fafaf
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Nov 2, 2022
5fc5550
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Nov 6, 2022
d74a60a
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Nov 14, 2022
68953df
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Nov 18, 2022
a0f87ef
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Nov 23, 2022
da92db8
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Dec 2, 2022
9e05df5
Merge branch 'main' into new-masstransit-enricher
nicolasderycke Dec 13, 2022
706f793
Update enrich callbacks for MassTransit
nicolasderycke Dec 13, 2022
dad802d
Remove unnecessary masstransit instrumentation event source
nicolasderycke Dec 13, 2022
50dbae7
Merge branch 'main' into new-masstransit-enricher
Kielek Dec 15, 2022
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
2 changes: 2 additions & 0 deletions src/OpenTelemetry.Instrumentation.MassTransit/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
* Remove .NET Framework 4.6.1. The minimum .NET Framework version supported is
.NET Framework 4.6.2 (by .NET Standard 2.0).
([#637](https://github.com/open-telemetry/opentelemetry-dotnet/issues/637))
* Added enricher for Masstransit activity
([#696](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/696))

## 1.0.0-beta.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,15 @@ public override void OnStartActivity(Activity activity, object payload)

ActivityInstrumentationHelper.SetActivitySourceProperty(activity, ActivitySource);
ActivityInstrumentationHelper.SetKindProperty(activity, this.GetActivityKind(activity));

try
{
this.options.EnrichWithRequestPayload?.Invoke(activity, payload);
}
catch (Exception ex)
{
this.options.EnrichWithException(activity, ex);
}
}
}

Expand All @@ -71,10 +80,12 @@ public override void OnStopActivity(Activity activity, object payload)
try
{
this.TransformMassTransitTags(activity);

this.options.EnrichWithResponsePayload?.Invoke(activity, payload);
}
catch (Exception ex)
{
MassTransitInstrumentationEventSource.Log.EnrichmentException(ex);
this.options.EnrichWithException(activity, ex);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@
// limitations under the License.
// </copyright>

using System;
using System.Diagnostics.Tracing;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Instrumentation.MassTransit.Implementation;

Expand All @@ -33,19 +31,4 @@ public void RequestIsFilteredOut(string eventName)
{
this.WriteEvent(1, eventName);
}

[NonEvent]
public void EnrichmentException(Exception ex)
{
if (this.IsEnabled(EventLevel.Error, (EventKeywords)(-1)))
{
this.EnrichmentException(ex.ToInvariantString());
}
}

[Event(2, Message = "Enrich threw exception. Exception {0}.", Level = EventLevel.Error)]
public void EnrichmentException(string exception)
{
this.WriteEvent(2, exception);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;

namespace OpenTelemetry.Instrumentation.MassTransit;

Expand All @@ -38,4 +41,32 @@ public class MassTransitInstrumentationOptions
/// Gets or sets traced operations set.
/// </summary>
public HashSet<string> TracedOperations { get; set; } = new HashSet<string>(DefaultTracedOperations);

/// <summary>
/// Gets or sets an action to enrich an Activity.
/// </summary>
/// <remarks>
/// <para><see cref="Activity"/>: the activity being enriched.</para>
/// <para>object: the raw object from which additional information can be extracted to enrich the activity.
/// The type of this object depends on the event.</para>
/// </remarks>
public Action<Activity, object> EnrichWithRequestPayload { get; set; }

/// <summary>
/// Gets or sets an action to enrich an Activity with <see cref="HttpResponseMessage"/>.
/// </summary>
/// <remarks>
/// <para><see cref="Activity"/>: the activity being enriched.</para>
/// <para>object: the raw object from which additional information can be extracted to enrich the activity.</para>
/// </remarks>
public Action<Activity, object> EnrichWithResponsePayload { get; set; }

/// <summary>
/// Gets or sets an action to enrich an Activity with <see cref="Exception"/>.
/// </summary>
/// <remarks>
/// <para><see cref="Activity"/>: the activity being enriched.</para>
/// <para>object: the raw object from which additional information can be extracted to enrich the activity.</para>
/// </remarks>
public Action<Activity, object> EnrichWithException { get; set; }
}
21 changes: 21 additions & 0 deletions src/OpenTelemetry.Instrumentation.MassTransit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,27 @@ services.AddOpenTelemetrySdk(x =>
});
```

Instrumentation can be configured via options overload for
`AddMassTransitInstrumentation` method:

```csharp
using var openTelemetry = Sdk.CreateTracerProviderBuilder()
.AddMassTransitInstrumentation(options =>
{
// Enable enriching an activity after it is created.
options.Enrich = (activity, eventName, rawObject) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example that actually makes use of the rawObject passed would be more helpful.

{
if (eventName == "OnStartActivity")
{
var messagingOperation = activity.OperationName.Split('.').Last().ToLower();
if (messagingOperation != "send")
activity.SetTag(SemanticConventions.AttributeMessagingOperation, messagingOperation);
}
};
})
.Build();
```

## Filter traced operations

For example you can trace only consume and handle operations using this snippet:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// limitations under the License.
// </copyright>

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -226,11 +227,26 @@ public async Task ShouldMapMassTransitTagsForHandleMessageToOpenTelemetrySpecifi

[Theory]
[InlineData(OperationName.Consumer.Consume)]
[InlineData(OperationName.Consumer.Consume, true)]
[InlineData(OperationName.Consumer.Consume, true, true)]
[InlineData(OperationName.Consumer.Handle)]
[InlineData(OperationName.Consumer.Handle, true)]
[InlineData(OperationName.Consumer.Handle, true, true)]
[InlineData(OperationName.Transport.Send)]
[InlineData(OperationName.Transport.Send, true)]
[InlineData(OperationName.Transport.Send, true, true)]
[InlineData(OperationName.Transport.Receive)]
public async Task MassTransitInstrumentationTestOptions(string operationName)
[InlineData(OperationName.Transport.Receive, true)]
[InlineData(OperationName.Transport.Receive, true, true)]
public async Task MassTransitInstrumentationTestOptions(
string operationName,
bool enrich = false,
bool enrichmentException = false)
{
bool enrichWithHttpRequestMessageCalled = false;
bool enrichWithHttpResponseMessageCalled = false;
bool enrichWithExceptionCalled = false;

using Activity activity = new Activity("Parent");
activity.SetParentId(
ActivityTraceId.CreateRandom(),
Expand All @@ -240,10 +256,31 @@ public async Task MassTransitInstrumentationTestOptions(string operationName)

var activityProcessor = new Mock<BaseProcessor<Activity>>();
using (Sdk.CreateTracerProviderBuilder()
.AddProcessor(activityProcessor.Object)
.AddMassTransitInstrumentation(o =>
o.TracedOperations = new HashSet<string>(new[] { operationName }))
.Build())
.AddProcessor(activityProcessor.Object)
.AddMassTransitInstrumentation(o =>
{
o.TracedOperations = new HashSet<string>(new[] { operationName });

if (enrich)
{
if (!enrichmentException)
{
o.EnrichWithRequestPayload = (activity, httpRequestMessage) => { enrichWithHttpRequestMessageCalled = true; };
}
else
{
o.EnrichWithRequestPayload = (activity, httpRequestMessage) =>
{
enrichWithHttpRequestMessageCalled = true;
throw new Exception("Error while enriching activity");
};
}

o.EnrichWithResponsePayload = (activity, httpResponseMessage) => { enrichWithHttpResponseMessageCalled = true; };
o.EnrichWithException = (activity, obj) => { enrichWithExceptionCalled = true; };
}
})
.Build())
{
var harness = new InMemoryTestHarness();
var consumerHarness = harness.Consumer<TestConsumer>();
Expand Down Expand Up @@ -271,6 +308,26 @@ await harness.InputQueueSendEndpoint.Send<TestMessage>(new
var consumes = this.GetActivitiesFromInvocationsByOperationName(activityProcessor.Invocations, operationName);

Assert.Single(consumes);

if (enrich)
{
Assert.True(enrichWithHttpRequestMessageCalled);
Assert.True(enrichWithHttpResponseMessageCalled);
}
else
{
Assert.False(enrichWithHttpRequestMessageCalled);
Assert.False(enrichWithHttpResponseMessageCalled);
}

if (enrichmentException)
{
Assert.True(enrichWithExceptionCalled);
}
else
{
Assert.False(enrichWithExceptionCalled);
}
}

[Fact]
Expand Down