Skip to content

Commit

Permalink
[release/8.0-preview5] Remove dependency from OpenTelemetry.Instrumen…
Browse files Browse the repository at this point in the history
…tation.StackExchangeRedis (#3198)

* Remove dependency from OpenTelemetry.Instrumentation.StackExchangeRedis

* Fix test builds

* Fix ActivitySourceName

* Undo IsAotCompatible change

* Update suppression comment to match OTel PR.

* Update code sync instruction for AOT

---------

Co-authored-by: Eric Erhardt <eric.erhardt@microsoft.com>
  • Loading branch information
sebastienros and eerhardt authored Mar 27, 2024
1 parent 4d3325b commit 4d551ed
Show file tree
Hide file tree
Showing 22 changed files with 2,033 additions and 21 deletions.
1 change: 0 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.7.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.7.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.7.0" />
<PackageVersion Include="OpenTelemetry.Instrumentation.StackExchangeRedis" Version="1.0.0-rc9.13" />
<!-- build dependencies -->
<PackageVersion Include="MicroBuild.Plugins.SwixBuild.Dotnet" Version="1.1.87-gba258badda" />
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.9.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

<ItemGroup>
<Compile Include="$(VendoringDir)OpenTelemetry.Instrumentation.SqlClient\**\*.cs" LinkBase="OpenTelemetry.Instrumentation.SqlClient" />
<Compile Include="$(VendoringDir)OpenTelemetry.Shared\**\*.cs" LinkBase="OpenTelemetry.Shared" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

<ItemGroup>
<Compile Include="$(VendoringDir)OpenTelemetry.Instrumentation.SqlClient\**\*.cs" LinkBase="OpenTelemetry.Instrumentation.SqlClient" />
<Compile Include="$(VendoringDir)OpenTelemetry.Shared\**\*.cs" LinkBase="OpenTelemetry.Shared" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ItemGroup>
<Compile Include="..\Common\ConfigurationSchemaAttributes.cs" Link="ConfigurationSchemaAttributes.cs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Aspire.StackExchange.Redis\Aspire.StackExchange.Redis.csproj" />
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,19 @@
<Compile Include="..\Common\ConfigurationSchemaAttributes.cs" Link="ConfigurationSchemaAttributes.cs" />
</ItemGroup>

<ItemGroup>
<Compile Include="$(VendoringDir)OpenTelemetry.Instrumentation.StackExchangeRedis\**\*.cs" LinkBase="OpenTelemetry.Instrumentation.StackExchangeRedis" />
<!-- Tests need access to StackExchangeRedisInstrumentationOptions which is made internal in /Vendoring -->
<InternalsVisibleTo Include="Aspire.StackExchange.Redis.Tests" />
<InternalsVisibleTo Include="Aspire.StackExchange.Redis.DistributedCaching.Tests" />
<InternalsVisibleTo Include="Aspire.StackExchange.Redis.OutputCaching.Tests" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="AspNetCore.HealthChecks.Redis" />
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" />
<PackageReference Include="OpenTelemetry.Instrumentation.StackExchangeRedis" />
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
<PackageReference Include="StackExchange.Redis" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ namespace Microsoft.Extensions.Hosting;
public static class AspireRedisExtensions
{
private const string DefaultConfigSectionName = "Aspire:StackExchange:Redis";
// Name taken from https://github.com/open-telemetry/opentelemetry-dotnet-contrib/blob/219e41848a810479c2024c2e48b8cb7ae3a5d3e6/src/OpenTelemetry.Instrumentation.StackExchangeRedis/StackExchangeRedisConnectionInstrumentation.cs#L21
private const string ActivitySourceName = "OpenTelemetry.Instrumentation.StackExchangeRedis";

/// <summary>
/// Registers <see cref="IConnectionMultiplexer"/> as a singleton in the services provided by the <paramref name="builder"/>.
Expand Down Expand Up @@ -153,7 +151,7 @@ private static void AddRedisClient(
builder.Services.AddOpenTelemetry()
.WithTracing(t =>
{
t.AddSource(ActivitySourceName);
t.AddSource(StackExchangeRedisConnectionInstrumentation.ActivitySourceName);
// This ensures the core Redis instrumentation services from OpenTelemetry.Instrumentation.StackExchangeRedis are added
t.ConfigureRedisInstrumentation(_ => { });
// This ensures that any logic performed by the AddInstrumentation method is executed (this is usually called by AddRedisInstrumentation())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable disable

using System.Diagnostics;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Instrumentation;

internal sealed class DiagnosticSourceListener : IObserver<KeyValuePair<string, object>>
{
private readonly ListenerHandler handler;

private readonly Action<string, string, Exception> logUnknownException;

public DiagnosticSourceListener(ListenerHandler handler, Action<string, string, Exception> logUnknownException)
{
Guard.ThrowIfNull(handler);

this.handler = handler;
this.logUnknownException = logUnknownException;
}

public void OnCompleted()
{
}

public void OnError(Exception error)
{
}

public void OnNext(KeyValuePair<string, object> value)
{
if (!this.handler.SupportsNullActivity && Activity.Current == null)
{
return;
}

try
{
this.handler.OnEventWritten(value.Key, value.Value);
}
catch (Exception ex)
{
this.logUnknownException?.Invoke(this.handler?.SourceName, value.Key, ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#nullable disable

using System.Diagnostics;
using OpenTelemetry.Internal;

namespace OpenTelemetry.Instrumentation;

internal sealed class DiagnosticSourceSubscriber : IDisposable, IObserver<DiagnosticListener>
{
private readonly List<IDisposable> listenerSubscriptions;
private readonly Func<string, ListenerHandler> handlerFactory;
private readonly Func<DiagnosticListener, bool> diagnosticSourceFilter;
private readonly Func<string, object, object, bool> isEnabledFilter;
private readonly Action<string, string, Exception> logUnknownException;
private long disposed;
private IDisposable allSourcesSubscription;

public DiagnosticSourceSubscriber(
ListenerHandler handler,
Func<string, object, object, bool> isEnabledFilter,
Action<string, string, Exception> logUnknownException)
: this(_ => handler, value => handler.SourceName == value.Name, isEnabledFilter, logUnknownException)
{
}

public DiagnosticSourceSubscriber(
Func<string, ListenerHandler> handlerFactory,
Func<DiagnosticListener, bool> diagnosticSourceFilter,
Func<string, object, object, bool> isEnabledFilter,
Action<string, string, Exception> logUnknownException)
{
Guard.ThrowIfNull(handlerFactory);

this.listenerSubscriptions = new List<IDisposable>();
this.handlerFactory = handlerFactory;
this.diagnosticSourceFilter = diagnosticSourceFilter;
this.isEnabledFilter = isEnabledFilter;
this.logUnknownException = logUnknownException;
}

public void Subscribe()
{
if (this.allSourcesSubscription == null)
{
this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this);
}
}

public void OnNext(DiagnosticListener value)
{
if ((Interlocked.Read(ref this.disposed) == 0) &&
this.diagnosticSourceFilter(value))
{
var handler = this.handlerFactory(value.Name);
var listener = new DiagnosticSourceListener(handler, this.logUnknownException);
var subscription = this.isEnabledFilter == null ?
value.Subscribe(listener) :
value.Subscribe(listener, this.isEnabledFilter);

lock (this.listenerSubscriptions)
{
this.listenerSubscriptions.Add(subscription);
}
}
}

public void OnCompleted()
{
}

public void OnError(Exception error)
{
}

/// <inheritdoc/>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposing)
{
if (Interlocked.CompareExchange(ref this.disposed, 1, 0) == 1)
{
return;
}

lock (this.listenerSubscriptions)
{
foreach (var listenerSubscription in this.listenerSubscriptions)
{
listenerSubscription?.Dispose();
}

this.listenerSubscriptions.Clear();
}

this.allSourcesSubscription?.Dispose();
this.allSourcesSubscription = null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics;

namespace OpenTelemetry.Instrumentation;

/// <summary>
/// ListenerHandler base class.
/// </summary>
internal abstract class ListenerHandler
{
/// <summary>
/// Initializes a new instance of the <see cref="ListenerHandler"/> class.
/// </summary>
/// <param name="sourceName">The name of the <see cref="ListenerHandler"/>.</param>
public ListenerHandler(string sourceName)
{
this.SourceName = sourceName;
}

/// <summary>
/// Gets the name of the <see cref="ListenerHandler"/>.
/// </summary>
public string SourceName { get; }

/// <summary>
/// Gets a value indicating whether the <see cref="ListenerHandler"/> supports NULL <see cref="Activity"/>.
/// </summary>
public virtual bool SupportsNullActivity { get; }

/// <summary>
/// Method called for an event which does not have 'Start', 'Stop' or 'Exception' as suffix.
/// </summary>
/// <param name="name">Custom name.</param>
/// <param name="payload">An object that represent the value being passed as a payload for the event.</param>
public virtual void OnEventWritten(string name, object payload)
{
}
}
Loading

0 comments on commit 4d551ed

Please sign in to comment.