PoC: Add support to testing OpenTracing integration (#186)
* Add OpenTracingShim to SDK initialization * Add OpenTracingShim as option to ConsoleApp * Change wrapper method to async * Match casing of other poc variables * Change log message to "tracer initialized" * Make OT span default on ConsoleApp * Fixes .vcxproj file for latest msbuild version. (#1495) Co-authored-by: Tony Redondo <tony.redondo@datadoghq.com>
This commit is contained in:
parent
3def931d53
commit
e34e3c9b41
|
|
@ -49,9 +49,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{BAF8
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "samples\ConsoleApp\ConsoleApp.csproj", "{2A172931-3439-4563-A6E5-525924DC2F76}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp", "samples\ConsoleApp\ConsoleApp.csproj", "{2A172931-3439-4563-A6E5-525924DC2F76}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed", "src\OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed\OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed.csproj", "{6690361C-CCD8-42C4-A5CF-82D554B03A3D}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed", "src\OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed\OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed.csproj", "{6690361C-CCD8-42C4-A5CF-82D554B03A3D}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp.SelfBootstrap", "samples\ConsoleApp.SelfBootstrap\ConsoleApp.SelfBootstrap.csproj", "{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleApp.SelfBootstrap", "samples\ConsoleApp.SelfBootstrap\ConsoleApp.SelfBootstrap.csproj", "{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTracingLibrary", "samples\OpenTracingLibrary\OpenTracingLibrary.csproj", "{7220BDBB-084D-40B3-A710-19E3C7147185}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
|
@ -155,6 +157,18 @@ Global
|
||||||
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x64.Build.0 = Release|Any CPU
|
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x64.Build.0 = Release|Any CPU
|
||||||
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x86.ActiveCfg = Release|Any CPU
|
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x86.Build.0 = Release|Any CPU
|
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF}.Release|x86.Build.0 = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|x64.Build.0 = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Debug|x86.Build.0 = Debug|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|x64.ActiveCfg = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|x64.Build.0 = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|x86.ActiveCfg = Release|Any CPU
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185}.Release|x86.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -168,6 +182,7 @@ Global
|
||||||
{2A172931-3439-4563-A6E5-525924DC2F76} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
|
{2A172931-3439-4563-A6E5-525924DC2F76} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
|
||||||
{6690361C-CCD8-42C4-A5CF-82D554B03A3D} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
|
{6690361C-CCD8-42C4-A5CF-82D554B03A3D} = {9E5F0022-0A50-40BF-AC6A-C3078585ECAB}
|
||||||
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
|
{7EA51D34-8E0E-4548-8A7F-5C6F9C3533AF} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
|
||||||
|
{7220BDBB-084D-40B3-A710-19E3C7147185} = {BAF8F246-3645-42AD-B1D0-0F7EAFBAB34A}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
|
SolutionGuid = {160A1D00-1F5B-40F8-A155-621B4459D78F}
|
||||||
|
|
|
||||||
|
|
@ -13,4 +13,8 @@
|
||||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="5.0.1" />
|
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="5.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\OpenTracingLibrary\OpenTracingLibrary.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -12,6 +12,16 @@ namespace ConsoleApp
|
||||||
private static async Task<int> Main()
|
private static async Task<int> Main()
|
||||||
{
|
{
|
||||||
using (var activity = MyActivitySource.StartActivity("Main"))
|
using (var activity = MyActivitySource.StartActivity("Main"))
|
||||||
|
{
|
||||||
|
await OpenTracingLibrary.Wrapper.WithOpenTracingSpanAsync("client", RunAsync);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task RunAsync()
|
||||||
|
{
|
||||||
|
using (var activity = MyActivitySource.StartActivity("RunAsync"))
|
||||||
{
|
{
|
||||||
activity?.SetTag("foo", "bar");
|
activity?.SetTag("foo", "bar");
|
||||||
|
|
||||||
|
|
@ -24,10 +34,8 @@ namespace ConsoleApp
|
||||||
|
|
||||||
var client = new HttpClient();
|
var client = new HttpClient();
|
||||||
Console.WriteLine("Calling client.GetAsync");
|
Console.WriteLine("Calling client.GetAsync");
|
||||||
await regularHttpClient.GetAsync("http://127.0.0.1:8080");
|
await client.GetAsync("http://127.0.0.1:8080");
|
||||||
Console.WriteLine("Called client.GetAsync");
|
Console.WriteLine("Called client.GetAsync");
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net452;net462;netstandard2.0</TargetFrameworks>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="OpenTracing" Version="0.12.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using OpenTracing.Util;
|
||||||
|
|
||||||
|
namespace OpenTracingLibrary
|
||||||
|
{
|
||||||
|
public static class Wrapper
|
||||||
|
{
|
||||||
|
public static async Task WithOpenTracingSpanAsync(string spanKind, Func<Task> wrapped)
|
||||||
|
{
|
||||||
|
var tracer = GlobalTracer.Instance;
|
||||||
|
Console.WriteLine($">>>>>>>>>>>>>>>>>>>>>>> OpenTracing.{tracer}");
|
||||||
|
using (var scope = tracer.BuildSpan("OpenTracing Span")
|
||||||
|
.WithTag("span.kind", spanKind)
|
||||||
|
.StartActive())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await wrapped();
|
||||||
|
scope.Span.Log("action success");
|
||||||
|
scope.Span.SetTag("action.success", true);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
scope.Span.SetTag("error", true);
|
||||||
|
var eventData = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{ "event", "error" },
|
||||||
|
{ "error.kind", "Exception" },
|
||||||
|
{ "error.object", ex },
|
||||||
|
{ "stack", ex.StackTrace.ToString() },
|
||||||
|
};
|
||||||
|
scope.Span.Log(eventData);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -28,7 +28,7 @@
|
||||||
<LIB_PATH>lib\</LIB_PATH>
|
<LIB_PATH>lib\</LIB_PATH>
|
||||||
<LIB_PLATFORM Condition="'$(Platform)'=='x64'">x64</LIB_PLATFORM>
|
<LIB_PLATFORM Condition="'$(Platform)'=='x64'">x64</LIB_PLATFORM>
|
||||||
<LIB_PLATFORM Condition="'$(Platform)'=='Win32' OR '$(Platform)'=='x86'">x86</LIB_PLATFORM>
|
<LIB_PLATFORM Condition="'$(Platform)'=='Win32' OR '$(Platform)'=='x86'">x86</LIB_PLATFORM>
|
||||||
<LIB_INCLUDES>$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\include;$(LIB_PATH)spdlog\include</LIB_INCLUDES>
|
<LIB_INCLUDES>$(CORECLR_PATH)\src\pal\prebuilt\inc;$(CORECLR_PATH)\src\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\include;$(LIB_PATH)spdlog\include</LIB_INCLUDES>
|
||||||
<LIB_BINARIES Condition="'$(Configuration)'=='Release'">$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\lib\fmt.lib</LIB_BINARIES>
|
<LIB_BINARIES Condition="'$(Configuration)'=='Release'">$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\lib\fmt.lib</LIB_BINARIES>
|
||||||
<LIB_BINARIES Condition="'$(Configuration)'=='Debug'">$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\debug\lib\fmtd.lib</LIB_BINARIES>
|
<LIB_BINARIES Condition="'$(Configuration)'=='Debug'">$(LIB_PATH)fmt_$(LIB_PLATFORM)-windows-static\debug\lib\fmtd.lib</LIB_BINARIES>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
@ -69,25 +69,21 @@
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<OutDir>bin\$(Configuration)\$(Platform)\static\</OutDir>
|
<OutDir>bin\$(Configuration)\$(Platform)\static\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\$(Platform)\static\</IntDir>
|
<IntDir>obj\$(Configuration)\$(Platform)\static\</IntDir>
|
||||||
<IncludePath>$(CORECLR_PATH)\src\pal\prebuilt\inc;$(CORECLR_PATH)\src\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<OutDir>bin\$(Configuration)\x86\static\</OutDir>
|
<OutDir>bin\$(Configuration)\x86\static\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\x86\static\</IntDir>
|
<IntDir>obj\$(Configuration)\x86\static\</IntDir>
|
||||||
<IncludePath>$(CORECLR_PATH)\src\pal\prebuilt\inc;$(CORECLR_PATH)\src\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>bin\$(Configuration)\$(Platform)\static\</OutDir>
|
<OutDir>bin\$(Configuration)\$(Platform)\static\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\$(Platform)\static\</IntDir>
|
<IntDir>obj\$(Configuration)\$(Platform)\static\</IntDir>
|
||||||
<IncludePath>$(CORECLR_PATH)\src\pal\prebuilt\inc;$(CORECLR_PATH)\src\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
<OutDir>bin\$(Configuration)\x86\static\</OutDir>
|
<OutDir>bin\$(Configuration)\x86\static\</OutDir>
|
||||||
<IntDir>obj\$(Configuration)\x86\static\</IntDir>
|
<IntDir>obj\$(Configuration)\x86\static\</IntDir>
|
||||||
<IncludePath>$(CORECLR_PATH)\src\pal\prebuilt\inc;$(CORECLR_PATH)\src\inc;$(VC_IncludePath);$(WindowsSDK_IncludePath);</IncludePath>
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed.Configuration;
|
using OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed.Configuration;
|
||||||
|
using OpenTelemetry.Context.Propagation;
|
||||||
|
using OpenTelemetry.Shims.OpenTracing;
|
||||||
using OpenTelemetry.Trace;
|
using OpenTelemetry.Trace;
|
||||||
|
|
||||||
namespace OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed
|
namespace OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed
|
||||||
|
|
@ -11,17 +13,17 @@ namespace OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class Instrumentation
|
public static class Instrumentation
|
||||||
{
|
{
|
||||||
|
private static readonly Process _process = Process.GetCurrentProcess();
|
||||||
private static int _firstInitialization = 1;
|
private static int _firstInitialization = 1;
|
||||||
|
|
||||||
private static TracerProvider _tracerProvider;
|
private static TracerProvider _tracerProvider;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initialize
|
/// Initialize the OpenTelemetry SDK with a pre-defined set of exporters, shims, and
|
||||||
|
/// instrumentations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void Initialize()
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
var p = Process.GetCurrentProcess();
|
|
||||||
Console.WriteLine($">>>>>>>>>>>>>>>>>>>>>>> Process: {p.ProcessName}({p.Id}), starting");
|
|
||||||
if (Interlocked.Exchange(ref _firstInitialization, value: 0) != 1)
|
if (Interlocked.Exchange(ref _firstInitialization, value: 0) != 1)
|
||||||
{
|
{
|
||||||
// Initialize() was already called before
|
// Initialize() was already called before
|
||||||
|
|
@ -43,14 +45,38 @@ namespace OpenTelemetry.AutoInstrumentation.ClrProfiler.Managed
|
||||||
.AddSource("OpenTelemetry.AutoInstrumentation.*");
|
.AddSource("OpenTelemetry.AutoInstrumentation.*");
|
||||||
|
|
||||||
_tracerProvider = builder.Build();
|
_tracerProvider = builder.Build();
|
||||||
Console.WriteLine($">>>>>>>>>>>>>>>>>>>>>>> Process: {p.ProcessName}({p.Id}), initialized");
|
Log("OpenTelemetry tracer initialized.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// TODO: Should we have our own logger like datadog has?
|
Log($"OpenTelemetry SDK load exception: {ex}");
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Instantiate the OpenTracing shim. The underlying OpenTelemetry tracer will create
|
||||||
|
// spans using the "OpenTelemetry.AutoInstrumentation.OpenTracingShim" source.
|
||||||
|
var openTracingShim = new TracerShim(
|
||||||
|
_tracerProvider.GetTracer("OpenTelemetry.AutoInstrumentation.OpenTracingShim"),
|
||||||
|
Propagators.DefaultTextMapPropagator);
|
||||||
|
|
||||||
|
// This registration must occur prior to any reference to the OpenTracing tracer:
|
||||||
|
// otherwise the no-op tracer is going to be used by OpenTracing instead.
|
||||||
|
OpenTracing.Util.GlobalTracer.Register(openTracingShim);
|
||||||
|
Log("OpenTracingShim loaded.");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log($"OpenTracingShim exception: {ex}");
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void Log(string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine($">>>>>>>>>>>>>>>>>>>>>>> Process: {_process.ProcessName}({_process.Id}): {message}");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc4" Condition="'$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'netcoreapp3.1'" />
|
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.0.0-rc4" Condition="'$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'netcoreapp3.1'" />
|
||||||
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.0.0-rc4" Condition="'$(TargetFramework)' != 'net452'" />
|
<PackageReference Include="OpenTelemetry.Exporter.Jaeger" Version="1.0.0-rc4" Condition="'$(TargetFramework)' != 'net452'" />
|
||||||
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.0.0-rc4" />
|
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.0.0-rc4" />
|
||||||
|
<PackageReference Include="OpenTelemetry.Shims.OpenTracing" Version="1.0.0-rc3" />
|
||||||
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="5.0.1" />
|
<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="5.0.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue