Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 22 additions & 1 deletion NETCORE/ThirdPartyNotices.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,4 +216,25 @@ http://www.apache.org/licenses/
See the License for the specific language governing permissions and
limitations under the License.
=========================================
END OF xunit and dotnet.test.xunit NOTICES, INFORMATION, AND LICENSE
END OF xunit and dotnet.test.xunit NOTICES, INFORMATION, AND LICENSE


3. OpenTelemetry .NET Contrib (https://github.com/open-telemetry/opentelemetry-dotnet-contrib)

%% OpenTelemetry .NET Contrib NOTICES, INFORMATION, AND LICENSE BEGIN HERE
=========================================
Copyright 2026 OpenTelemetry Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
=========================================
END OF OpenTelemetry .NET Contrib NOTICES, INFORMATION, AND LICENSE
10 changes: 10 additions & 0 deletions NETCORE/src/Shared/Shared.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,15 @@
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ApplicationInsightsExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Extensions\ApplicationInsightsServiceOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Internals\ApplicationNameProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AppServiceResourceDetector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AzureContainerAppsResourceDetector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AzureResourceBuilderExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AzureVmMetaDataRequestor.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AzureVmMetadataResponse.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\AzureVMResourceDetector.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\Guard.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\ResourceAttributeConstants.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\ResourceSemanticConventions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Vendoring\OpenTelemetry.Resources.Azure\SourceGenerationContext.cs" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#nullable enable

namespace Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources.Azure
{
using System;
using System.Collections.Generic;
using global::OpenTelemetry.Resources;

/// <summary>
/// Resource detector for Azure AppService environment.
/// </summary>
internal sealed class AppServiceResourceDetector : IResourceDetector
{
internal static readonly IReadOnlyDictionary<string, string> AppServiceResourceAttributes = new Dictionary<string, string>
{
{ ResourceSemanticConventions.AttributeCloudRegion, ResourceAttributeConstants.AppServiceRegionNameEnvVar },
{ ResourceSemanticConventions.AttributeDeploymentEnvironment, ResourceAttributeConstants.AppServiceSlotNameEnvVar },
{ ResourceSemanticConventions.AttributeHostId, ResourceAttributeConstants.AppServiceHostNameEnvVar },
{ ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AppServiceInstanceIdEnvVar },
{ ResourceAttributeConstants.AzureAppServiceStamp, ResourceAttributeConstants.AppServiceStampNameEnvVar },
};

/// <inheritdoc/>
public Resource Detect()
{
List<KeyValuePair<string, object>> attributeList = new List<KeyValuePair<string, object>>();

try
{
var websiteSiteName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceSiteNameEnvVar);

if (websiteSiteName != null)
{
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, websiteSiteName));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureAppServicePlatformValue));

var azureResourceUri = GetAzureResourceURI(websiteSiteName);
if (azureResourceUri != null)
{
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudResourceId, azureResourceUri));
}

foreach (var kvp in AppServiceResourceAttributes)
{
var attributeValue = Environment.GetEnvironmentVariable(kvp.Value);
if (attributeValue != null)
{
attributeList.Add(new KeyValuePair<string, object>(kvp.Key, attributeValue));
}
}
}
}
catch
{
// TODO: log exception.
return Resource.Empty;
}

return new Resource(attributeList);
}

private static string? GetAzureResourceURI(string websiteSiteName)
{
var websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar);
var websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty;

#if NET
var idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal);
#else
var idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal);
#endif
var subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName;

return string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)
? null
: $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

namespace Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources.Azure
{
using System;
using System.Collections.Generic;
using global::OpenTelemetry.Resources;

/// <summary>
/// Resource detector for Azure Container Apps environment.
/// </summary>
internal sealed class AzureContainerAppsResourceDetector : IResourceDetector
{
internal static readonly IReadOnlyDictionary<string, string> AzureContainerAppResourceAttributes = new Dictionary<string, string>
{
{ ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar },
{ ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppsRevisionEnvVar },
};

internal static readonly IReadOnlyDictionary<string, string> AzureContainerAppJobResourceAttributes = new Dictionary<string, string>
{
{ ResourceSemanticConventions.AttributeServiceInstance, ResourceAttributeConstants.AzureContainerAppsReplicaNameEnvVar },
{ ResourceSemanticConventions.AttributeServiceVersion, ResourceAttributeConstants.AzureContainerAppJobExecutionNameEnvVar },
};

/// <inheritdoc/>
public Resource Detect()
{
List<KeyValuePair<string, object>> attributeList = new List<KeyValuePair<string, object>>();
try
{
var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar);
var containerAppJobName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppJobNameEnvVar);

if (containerAppName != null)
{
AddBaseAttributes(attributeList, containerAppName);

AddResourceAttributes(attributeList, AzureContainerAppResourceAttributes);
}
else if (containerAppJobName != null)
{
AddBaseAttributes(attributeList, containerAppJobName);

AddResourceAttributes(attributeList, AzureContainerAppJobResourceAttributes);
}
}
catch
{
// TODO: log exception.
return Resource.Empty;
}

return new Resource(attributeList);
}

private static void AddResourceAttributes(List<KeyValuePair<string, object>> attributeList, IReadOnlyDictionary<string, string> resourceAttributes)
{
foreach (var kvp in resourceAttributes)
{
var attributeValue = Environment.GetEnvironmentVariable(kvp.Value);
if (attributeValue != null)
{
attributeList.Add(new KeyValuePair<string, object>(kvp.Key, attributeValue));
}
}
}

private static void AddBaseAttributes(List<KeyValuePair<string, object>> attributeList, string serviceName)
{
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeServiceName, serviceName));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudProvider, ResourceAttributeConstants.AzureCloudProviderValue));
attributeList.Add(new KeyValuePair<string, object>(ResourceSemanticConventions.AttributeCloudPlatform, ResourceAttributeConstants.AzureContainerAppsPlatformValue));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

namespace Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources
{
using global::OpenTelemetry.Resources;
using Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources.Azure;

/// <summary>
/// Extension methods to simplify registering of Azure resource detectors.
/// </summary>
internal static class AzureResourceBuilderExtensions
{
/// <summary>
/// Enables Azure App Service resource detector.
/// </summary>
/// <param name="builder">The <see cref="ResourceBuilder"/> being configured.</param>
/// <returns>The instance of <see cref="ResourceBuilder"/> being configured.</returns>
public static ResourceBuilder AddAzureAppServiceDetector(this ResourceBuilder builder)
{
Guard.ThrowIfNull(builder);
return builder.AddDetector(new AppServiceResourceDetector());
}

/// <summary>
/// Enables Azure VM resource detector.
/// </summary>
/// <param name="builder">The <see cref="ResourceBuilder"/> being configured.</param>
/// <returns>The instance of <see cref="ResourceBuilder"/> being configured.</returns>
public static ResourceBuilder AddAzureVMDetector(this ResourceBuilder builder)
{
Guard.ThrowIfNull(builder);
return builder.AddDetector(new AzureVMResourceDetector());
}

/// <summary>
/// Enables Azure Container Apps resource detector.
/// </summary>
/// <param name="builder">The <see cref="ResourceBuilder"/> being configured.</param>
/// <returns>The instance of <see cref="ResourceBuilder"/> being configured.</returns>
public static ResourceBuilder AddAzureContainerAppsDetector(this ResourceBuilder builder)
{
Guard.ThrowIfNull(builder);
return builder.AddDetector(new AzureContainerAppsResourceDetector());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
#nullable enable

namespace Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources.Azure
{
using System.Collections.Generic;
using global::OpenTelemetry;
using global::OpenTelemetry.Resources;

/// <summary>
/// Resource detector for Azure VM environment.
/// </summary>
internal sealed class AzureVMResourceDetector : IResourceDetector
{
internal static readonly IReadOnlyCollection<string> ExpectedAzureAmsFields =
[
ResourceAttributeConstants.AzureVmScaleSetName,
ResourceAttributeConstants.AzureVmSku,
ResourceSemanticConventions.AttributeCloudPlatform,
ResourceSemanticConventions.AttributeCloudProvider,
ResourceSemanticConventions.AttributeCloudRegion,
ResourceSemanticConventions.AttributeCloudResourceId,
ResourceSemanticConventions.AttributeHostId,
ResourceSemanticConventions.AttributeHostName,
ResourceSemanticConventions.AttributeHostType,
ResourceSemanticConventions.AttributeOsType,
ResourceSemanticConventions.AttributeOsVersion,
ResourceSemanticConventions.AttributeServiceInstance
];

private static Resource? vmResource;

/// <inheritdoc/>
public Resource Detect()
{
try
{
if (vmResource != null)
{
return vmResource;
}

// Prevents the http operations from being instrumented.
using var scope = SuppressInstrumentationScope.Begin();

var vmMetaDataResponse = AzureVmMetaDataRequestor.GetAzureVmMetaDataResponse();
if (vmMetaDataResponse == null)
{
vmResource = Resource.Empty;

return vmResource;
}

var attributeList = new List<KeyValuePair<string, object>>(ExpectedAzureAmsFields.Count);
foreach (var field in ExpectedAzureAmsFields)
{
attributeList.Add(new KeyValuePair<string, object>(field, vmMetaDataResponse.GetValueForField(field)));
}

vmResource = new Resource(attributeList);
}
catch
{
// TODO: log exception.
vmResource = Resource.Empty;
}

return vmResource;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
namespace Microsoft.ApplicationInsights.Shared.Vendoring.OpenTelemetry.Resources.Azure
{
using System;
using System.Net.Http;
#nullable enable

using System.Text.Json;

internal static class AzureVmMetaDataRequestor
{
private const string AzureVmMetadataEndpointURL = "http://169.254.169.254/metadata/instance/compute?api-version=2021-12-13&format=json";

public static Func<AzureVmMetadataResponse?> GetAzureVmMetaDataResponse { get; internal set; } = GetAzureVmMetaDataResponseDefault!;

public static AzureVmMetadataResponse? GetAzureVmMetaDataResponseDefault()
{
using var httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(2) };

httpClient.DefaultRequestHeaders.Add("Metadata", "True");
#pragma warning disable AZC0102 // Do not use GetAwaiter().GetResult().
#pragma warning disable AZC0104 // Use EnsureCompleted() directly on asynchronous method return value.
var res = httpClient.GetStringAsync(new Uri(AzureVmMetadataEndpointURL)).ConfigureAwait(false).GetAwaiter().GetResult();
#pragma warning restore AZC0104 // Use EnsureCompleted() directly on asynchronous method return value.
#pragma warning restore AZC0102 // Do not use GetAwaiter().GetResult().

if (res != null)
{
#if NET
return JsonSerializer.Deserialize(res, SourceGenerationContext.Default.AzureVmMetadataResponse);
#else
return JsonSerializer.Deserialize<AzureVmMetadataResponse>(res);
#endif
}

return null;
}
}
}
Loading
Loading