Skip to content
Open
3 changes: 2 additions & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<PackageVersion Include="Microsoft.DotNet.PlatformAbstractions" Version="3.1.6" />
<PackageVersion Include="Microsoft.DotNet.RemoteExecutor" Version="11.0.0-beta.25476.3" />
<PackageVersion Include="Microsoft.DotNet.XUnitExtensions" Version="11.0.0-beta.25476.3" />
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.3" />
<PackageVersion Include="Microsoft.Identity.Client" Version="4.78.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.14.1" />
<PackageVersion Include="Microsoft.SqlServer.SqlManagementObjects" Version="172.76.0" />
Expand Down Expand Up @@ -109,7 +110,7 @@
<PackageVersion Include="Microsoft.IdentityModel.JsonWebTokens" Version="8.14.0" />
<PackageVersion Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" Version="8.14.0" />
<PackageVersion Include="System.Buffers" Version="4.6.1" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="8.0.1" />
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="10.0.3" />
<PackageVersion Include="System.Memory" Version="4.6.3" />
<PackageVersion Include="System.Runtime.InteropServices.RuntimeInformation" Version="4.3.0" />
<PackageVersion Include="System.Text.Json" Version="8.0.6" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,14 @@
<None Include="PackageReadme.md" Pack="true" PackagePath="README.md" />
</ItemGroup>

<!--
Refer to the Logging package via project or package reference
depending on our build parameters.
-->
<ItemGroup Condition="'$(ReferenceType)' == 'Project'">
<ProjectReference Include="$(RepoRoot)/src/Microsoft.Data.SqlClient.Extensions/Logging/src/Logging.csproj"/>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
</ItemGroup>
<ItemGroup Condition="'$(ReferenceType)' == 'Package'">
<PackageReference Include="Microsoft.Data.SqlClient.Extensions.Logging" />

<ItemGroup>
<Compile Include="$(RepoRoot)/src/Microsoft.Data.SqlClient.Extensions/Common/Abstractions/Logging/Logger.cs">
<Link>Logging/Logger.cs</Link>
</Compile>
</ItemGroup>

<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

namespace Microsoft.Data.SqlClient.Extensions.Abstractions.Logging;

/// <summary>
/// The names of logging categories written to by Microsoft.Data.SqlClient.
/// </summary>
public static class CategoryNames
{
/// <summary>
/// Captures basic application flow trace events.
/// </summary>
public const string Trace = "Microsoft.Data.SqlClient.Logging.Trace";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using Microsoft.Extensions.Logging;

namespace Microsoft.Data.SqlClient.Extensions.Abstractions.Logging;

Comment on lines +1 to +4
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

This new source file is missing the standard .NET Foundation/MIT license header that appears at the top of other files in the repo. Please add the repo’s standard header before the first using directive.

Copilot uses AI. Check for mistakes.
internal static partial class LogMessages
{
[LoggerMessage(EventId = 1, EventName = nameof(AssemblyNotFound),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | MDS assembly={{assemblyName}} not found; Get/SetProvider() will not function.")]
public static partial void AssemblyNotFound(this ILogger logger, string assemblyName);

[LoggerMessage(EventId = 2, EventName = nameof(AuthManagerClassNotFound),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | MDS auth manager class {{className}} not found; Get/SetProvider() will not function.")]
public static partial void AuthManagerClassNotFound(this ILogger logger, string className);

[LoggerMessage(EventId = 3, EventName = nameof(GetProviderMethodNotFound),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | MDS GetProvider() method not found; Get/SetProvider() will not function.")]
public static partial void GetProviderMethodNotFound(this ILogger logger);

[LoggerMessage(EventId = 4, EventName = nameof(SetProviderMethodNotFound),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | MDS SetProvider() method not found; Get/SetProvider() will not function.")]
public static partial void SetProviderMethodNotFound(this ILogger logger);

[LoggerMessage(EventId = 5, EventName = nameof(AssemblyNotFoundOrUsable),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | MDS assembly={{assemblyName}} not found or not usable; Get/SetProvider() will not function: {{exceptionString}}")]
public static partial void AssemblyNotFoundOrUsable(this ILogger logger, string assemblyName, string exceptionString);

[LoggerMessage(EventId = 6, EventName = nameof(GetProviderInvocationFailed),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | GetProvider() invocation failed: {{exceptionType}}: {{exceptionString}}")]
public static partial void GetProviderInvocationFailed(this ILogger logger, string exceptionType, string exceptionString);

[LoggerMessage(EventId = 7, EventName = nameof(SetProviderInvocationReturnedNull),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | SetProvider() invocation returned null; translating to false.")]
public static partial void SetProviderInvocationReturnedNull(this ILogger logger);

[LoggerMessage(EventId = 8, EventName = nameof(SetProviderInvocationFailed),
Level = LogLevel.Warning,
Message = $"SqlAuthenticationProvider.Internal | SetProvider() invocation failed: {{exceptionType}}: {{exceptionString}}")]
public static partial void SetProviderInvocationFailed(this ILogger logger, string exceptionType, string exceptionString);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Runtime.CompilerServices;
using Microsoft.Extensions.Logging;

namespace Microsoft.Data.SqlClient.Extensions.Abstractions.Logging;
Comment on lines +1 to +4
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

This new source file is missing the standard .NET Foundation/MIT license header that appears at the top of other files in the repo. Please add the repo’s standard header before the first using directive.

Copilot uses AI. Check for mistakes.

/// <summary>
/// <see cref="ILogger"/> extension methods for use by Microsoft.Data.SqlClient.
/// </summary>
public static class LoggerExtensions
{
/// <summary>
/// Begins a logical operation scope, defined by the class name, calling member and a scope identifier.
/// </summary>
/// <param name="logger"><see cref="ILogger"/> instance to use to begin the scope.</param>
/// <param name="className">Class containing the calling member.</param>
/// <param name="memberName">Name of the calling member.</param>
/// <returns>An <see cref="IDisposable"/> that ends the logical operation scope on dispose.</returns>
public static IDisposable? BeginMemberScope(this ILogger logger, string className, [CallerMemberName] string memberName = "") =>
logger.BeginScope($"{className}.{memberName} | INFO | SCOPE | Entering Scope {{0}}");
}
Comment on lines +9 to +20
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

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

BeginMemberScope is a public extension on ILogger, but it relies on SqlClient’s EventSource scope formatting behavior (embedding a "{0}" placeholder for a later scopeId substitution). With a normal ILogger implementation, this will likely produce confusing scopes that literally contain "{0}". Consider making this extension internal, or changing it to use a provider-agnostic scope state (e.g., structured values) that doesn’t rely on a second formatting pass.

Copilot uses AI. Check for mistakes.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.Data.SqlClient.Extensions.Abstractions;
using Microsoft.Data.SqlClient.Extensions.Abstractions.Logging;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Microsoft.Data.SqlClient;

Expand Down Expand Up @@ -48,8 +49,7 @@ static Internal()

if (assembly is null)
{
Log($"MDS assembly={assemblyName} not found; " +
"Get/SetProvider() will not function");
Logger.TraceLogger?.AssemblyNotFound(assemblyName);
return;
}

Expand All @@ -62,8 +62,7 @@ static Internal()

if (manager is null)
{
Log($"MDS auth manager manager class={className} not found; " +
"Get/SetProvider() will not function");
Logger.TraceLogger?.AuthManagerClassNotFound(className);
return;
}

Expand All @@ -74,8 +73,7 @@ static Internal()

if (_getProvider is null)
{
Log($"MDS GetProvider() method not found; " +
"GetProvider() will not function");
Logger.TraceLogger?.GetProviderMethodNotFound();
}

_setProvider = manager.GetMethod(
Expand All @@ -84,8 +82,7 @@ static Internal()

if (_setProvider is null)
{
Log($"MDS SetProvider() method not found; " +
"SetProvider() will not function");
Logger.TraceLogger?.SetProviderMethodNotFound();
}
}
// All of these exceptions mean we couldn't find the get/set
Expand All @@ -96,8 +93,7 @@ or BadImageFormatException
or FileLoadException
or FileNotFoundException)
{
Log($"MDS assembly={assemblyName} not found or not usable; " +
$"Get/SetProvider() will not function: {ex} ");
Logger.TraceLogger?.AssemblyNotFoundOrUsable(assemblyName, ex.ToString());
}
// Any other exceptions are fatal.
}
Expand Down Expand Up @@ -132,8 +128,7 @@ or MethodAccessException
or NotSupportedException
or TargetInvocationException)
{
Log($"GetProvider() invocation failed: " +
$"{ex.GetType().Name}: {ex.Message}");
Logger.TraceLogger?.GetProviderInvocationFailed(ex.GetType().Name, ex.ToString());
return null;
}
}
Expand Down Expand Up @@ -169,8 +164,7 @@ internal static bool SetProvider(

if (!result.HasValue)
{
Log($"SetProvider() invocation returned null; " +
"translating to false");
Logger.TraceLogger?.SetProviderInvocationReturnedNull();
return false;
}

Expand All @@ -183,15 +177,9 @@ or MethodAccessException
or NotSupportedException
or TargetInvocationException)
{
Log($"SetProvider() invocation failed: " +
$"{ex.GetType().Name}: {ex.Message}");
Logger.TraceLogger?.SetProviderInvocationFailed(ex.GetType().Name, ex.ToString());
return false;
}
}

private static void Log(string message)
{
SqlClientEventSource.Log.TryTraceEvent("SqlAuthenticationProvider.Internal | {0}", message);
}
}
}
Loading
Loading