Skip to content

Commit ecf6604

Browse files
author
Timothy Mothra
authored
[AzureMonitorDistro] update vendored code for ResourceDetector (Azure#49351)
* upgrade OTel to v1.10 and fix api conflicts * bugfix: should not create exception telemetry when message is empty * test bug: fixing bug with requestData.Success * adding support for net9.0 to csproj and global.json * upgrade OTel to v1.10 and fix api conflicts * bugfix: should not create exception telemetry when message is empty * test bug: fixing bug with requestData.Success * adding support for net9.0 to csproj and global.json * cleanup * bump version 1.11.* * fix for Http * changelogs * refresh vendored code * breaking change * hack fixes for conflicts * changelog placeholder * changelog * fix unit tests * comment * changelog * revert changes to sqlclient * revert changes * cleanup changelog * revert change to SemanticConventions * fix changelog
1 parent aa353a4 commit ecf6604

17 files changed

+711
-105
lines changed

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
### Other Changes
1212

13+
* Updated the code of vendored resource detector library `OpenTelemetry.Resources.Azure` from the OpenTelemetry .NET contrib repository.
14+
Code has been updated to [1.11.0-beta.2](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/tree/Resources.Azure-1.11.0-beta.2/src/OpenTelemetry.Resources.Azure).
15+
([#49351](https://github.com/Azure/azure-sdk-for-net/pull/49351))
16+
1317
## 1.3.0-beta.3 (2025-04-08)
1418

1519
### Other Changes

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/OpenTelemetry.Resources.Azure/AppServiceResourceDetector.cs

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ internal sealed class AppServiceResourceDetector : IResourceDetector
2222
/// <inheritdoc/>
2323
public Resource Detect()
2424
{
25-
List<KeyValuePair<string, object>> attributeList = new();
25+
List<KeyValuePair<string, object>> attributeList = [];
2626

2727
try
2828
{
@@ -61,21 +61,18 @@ public Resource Detect()
6161

6262
private static string? GetAzureResourceURI(string websiteSiteName)
6363
{
64-
string? websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar);
65-
string websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty;
64+
var websiteResourceGroup = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceResourceGroupEnvVar);
65+
var websiteOwnerName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AppServiceOwnerNameEnvVar) ?? string.Empty;
6666

6767
#if NET
68-
int idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal);
68+
var idx = websiteOwnerName.IndexOf('+', StringComparison.Ordinal);
6969
#else
70-
int idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal);
70+
var idx = websiteOwnerName.IndexOf("+", StringComparison.Ordinal);
7171
#endif
72-
string subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName;
72+
var subscriptionId = idx > 0 ? websiteOwnerName.Substring(0, idx) : websiteOwnerName;
7373

74-
if (string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId))
75-
{
76-
return null;
77-
}
78-
79-
return $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}";
74+
return string.IsNullOrEmpty(websiteResourceGroup) || string.IsNullOrEmpty(subscriptionId)
75+
? null
76+
: $"/subscriptions/{subscriptionId}/resourceGroups/{websiteResourceGroup}/providers/Microsoft.Web/sites/{websiteSiteName}";
8077
}
8178
}

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/OpenTelemetry.Resources.Azure/AzureContainerAppsResourceDetector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal sealed class AzureContainerAppsResourceDetector : IResourceDetector
2525
/// <inheritdoc/>
2626
public Resource Detect()
2727
{
28-
List<KeyValuePair<string, object>> attributeList = new List<KeyValuePair<string, object>>();
28+
List<KeyValuePair<string, object>> attributeList = [];
2929
try
3030
{
3131
var containerAppName = Environment.GetEnvironmentVariable(ResourceAttributeConstants.AzureContainerAppsNameEnvVar);

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/OpenTelemetry.Resources.Azure/AzureVMResourceDetector.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ namespace OpenTelemetry.Resources.Azure;
1010
/// </summary>
1111
internal sealed class AzureVMResourceDetector : IResourceDetector
1212
{
13-
internal static readonly IReadOnlyCollection<string> ExpectedAzureAmsFields = new string[]
14-
{
13+
internal static readonly IReadOnlyCollection<string> ExpectedAzureAmsFields =
14+
[
1515
ResourceAttributeConstants.AzureVmScaleSetName,
1616
ResourceAttributeConstants.AzureVmSku,
1717
ResourceSemanticConventions.AttributeCloudPlatform,
@@ -23,8 +23,8 @@ internal sealed class AzureVMResourceDetector : IResourceDetector
2323
ResourceSemanticConventions.AttributeHostType,
2424
ResourceSemanticConventions.AttributeOsType,
2525
ResourceSemanticConventions.AttributeOsVersion,
26-
ResourceSemanticConventions.AttributeServiceInstance,
27-
};
26+
ResourceSemanticConventions.AttributeServiceInstance
27+
];
2828

2929
private static Resource? vmResource;
3030

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/OpenTelemetry.Resources.Azure/AzureVmMetadataResponse.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ internal string GetValueForField(string fieldName)
8080
case ResourceAttributeConstants.AzureVmSku:
8181
amsValue = this.Sku;
8282
break;
83+
default:
84+
break;
8385
}
8486

8587
amsValue ??= string.Empty;

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/Shared/AssemblyVersionExtensions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
#nullable enable
5-
64
using System.Diagnostics;
75
using System.Reflection;
86

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
using System.Diagnostics.CodeAnalysis;
5+
using Microsoft.Extensions.Configuration;
6+
7+
namespace OpenTelemetry.Internal;
8+
9+
/// <summary>
10+
/// Helper class for Database Semantic Conventions.
11+
/// </summary>
12+
/// <remarks>
13+
/// Due to a breaking change in the semantic convention, affected instrumentation libraries
14+
/// must inspect an environment variable to determine which attributes to emit.
15+
/// This is expected to be removed when the instrumentation libraries reach Stable.
16+
/// <see href="https://github.com/open-telemetry/semantic-conventions/blob/v1.28.0/docs/database/database-spans.md"/>.
17+
/// </remarks>
18+
internal static class DatabaseSemanticConventionHelper
19+
{
20+
internal const string SemanticConventionOptInKeyName = "OTEL_SEMCONV_STABILITY_OPT_IN";
21+
internal static readonly char[] Separator = [',', ' '];
22+
23+
[Flags]
24+
internal enum DatabaseSemanticConvention
25+
{
26+
/// <summary>
27+
/// Instructs an instrumentation library to emit the old experimental Database attributes.
28+
/// </summary>
29+
Old = 0x1,
30+
31+
/// <summary>
32+
/// Instructs an instrumentation library to emit the new, v1.28.0 Database attributes.
33+
/// </summary>
34+
New = 0x2,
35+
36+
/// <summary>
37+
/// Instructs an instrumentation library to emit both the old and new attributes.
38+
/// </summary>
39+
Dupe = Old | New,
40+
}
41+
42+
public static DatabaseSemanticConvention GetSemanticConventionOptIn(IConfiguration configuration)
43+
{
44+
if (TryGetConfiguredValues(configuration, out var values))
45+
{
46+
if (values.Contains("database/dup"))
47+
{
48+
return DatabaseSemanticConvention.Dupe;
49+
}
50+
else if (values.Contains("database"))
51+
{
52+
return DatabaseSemanticConvention.New;
53+
}
54+
}
55+
56+
return DatabaseSemanticConvention.Old;
57+
}
58+
59+
private static bool TryGetConfiguredValues(IConfiguration configuration, [NotNullWhen(true)] out HashSet<string>? values)
60+
{
61+
try
62+
{
63+
var stringValue = configuration[SemanticConventionOptInKeyName];
64+
65+
if (string.IsNullOrWhiteSpace(stringValue))
66+
{
67+
values = null;
68+
return false;
69+
}
70+
71+
var stringValues = stringValue!.Split(separator: Separator, options: StringSplitOptions.RemoveEmptyEntries);
72+
values = new HashSet<string>(stringValues, StringComparer.OrdinalIgnoreCase);
73+
return true;
74+
}
75+
catch
76+
{
77+
values = null;
78+
return false;
79+
}
80+
}
81+
}

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/Shared/DiagnosticSourceListener.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
#nullable enable
5-
64
using System.Diagnostics;
75
using OpenTelemetry.Internal;
86

sdk/monitor/Azure.Monitor.OpenTelemetry.AspNetCore/src/Vendoring/Shared/DiagnosticSourceSubscriber.cs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
#nullable enable
5-
64
using System.Diagnostics;
75
using OpenTelemetry.Internal;
86

@@ -34,7 +32,7 @@ public DiagnosticSourceSubscriber(
3432
{
3533
Guard.ThrowIfNull(handlerFactory);
3634

37-
this.listenerSubscriptions = new List<IDisposable>();
35+
this.listenerSubscriptions = [];
3836
this.handlerFactory = handlerFactory;
3937
this.diagnosticSourceFilter = diagnosticSourceFilter;
4038
this.isEnabledFilter = isEnabledFilter;
@@ -43,10 +41,7 @@ public DiagnosticSourceSubscriber(
4341

4442
public void Subscribe()
4543
{
46-
if (this.allSourcesSubscription == null)
47-
{
48-
this.allSourcesSubscription = DiagnosticListener.AllListeners.Subscribe(this);
49-
}
44+
this.allSourcesSubscription ??= DiagnosticListener.AllListeners.Subscribe(this);
5045
}
5146

5247
public void OnNext(DiagnosticListener value)
@@ -91,15 +86,22 @@ private void Dispose(bool disposing)
9186

9287
lock (this.listenerSubscriptions)
9388
{
94-
foreach (var listenerSubscription in this.listenerSubscriptions)
89+
if (disposing)
9590
{
96-
listenerSubscription?.Dispose();
91+
foreach (var listenerSubscription in this.listenerSubscriptions)
92+
{
93+
listenerSubscription?.Dispose();
94+
}
9795
}
9896

9997
this.listenerSubscriptions.Clear();
10098
}
10199

102-
this.allSourcesSubscription?.Dispose();
100+
if (disposing)
101+
{
102+
this.allSourcesSubscription?.Dispose();
103+
}
104+
103105
this.allSourcesSubscription = null;
104106
}
105107
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// <auto-generated /> (Turns off StyleCop analysis in this file.)
2+
// Licensed to the .NET Foundation under one or more agreements.
3+
// The .NET Foundation licenses this file to you under the MIT license.
4+
5+
#nullable enable
6+
7+
using System;
8+
using System.Collections;
9+
using System.Collections.Generic;
10+
11+
namespace Microsoft.Extensions.Configuration.EnvironmentVariables
12+
{
13+
/// <summary>
14+
/// An environment variable based <see cref="ConfigurationProvider"/>.
15+
/// </summary>
16+
internal sealed class EnvironmentVariablesConfigurationProvider : ConfigurationProvider
17+
{
18+
private readonly string _prefix;
19+
private readonly string _normalizedPrefix;
20+
21+
/// <summary>
22+
/// Initializes a new instance.
23+
/// </summary>
24+
public EnvironmentVariablesConfigurationProvider()
25+
{
26+
_prefix = string.Empty;
27+
_normalizedPrefix = string.Empty;
28+
}
29+
30+
/// <summary>
31+
/// Initializes a new instance with the specified prefix.
32+
/// </summary>
33+
/// <param name="prefix">A prefix used to filter the environment variables.</param>
34+
public EnvironmentVariablesConfigurationProvider(string? prefix)
35+
{
36+
_prefix = prefix ?? string.Empty;
37+
_normalizedPrefix = Normalize(_prefix);
38+
}
39+
40+
/// <summary>
41+
/// Loads the environment variables.
42+
/// </summary>
43+
public override void Load() =>
44+
Load(Environment.GetEnvironmentVariables());
45+
46+
/// <summary>
47+
/// Generates a string representing this provider name and relevant details.
48+
/// </summary>
49+
/// <returns> The configuration name. </returns>
50+
public override string ToString()
51+
=> $"{GetType().Name} Prefix: '{_prefix}'";
52+
53+
internal void Load(IDictionary envVariables)
54+
{
55+
var data = new Dictionary<string, string?>(StringComparer.OrdinalIgnoreCase);
56+
57+
IDictionaryEnumerator e = envVariables.GetEnumerator();
58+
try
59+
{
60+
while (e.MoveNext())
61+
{
62+
string key = (string)e.Entry.Key;
63+
string? value = (string?)e.Entry.Value;
64+
AddIfNormalizedKeyMatchesPrefix(data, Normalize(key), value);
65+
}
66+
}
67+
finally
68+
{
69+
(e as IDisposable)?.Dispose();
70+
}
71+
72+
Data = data;
73+
}
74+
75+
private void AddIfNormalizedKeyMatchesPrefix(Dictionary<string, string?> data, string normalizedKey, string? value)
76+
{
77+
if (normalizedKey.StartsWith(_normalizedPrefix, StringComparison.OrdinalIgnoreCase))
78+
{
79+
data[normalizedKey.Substring(_normalizedPrefix.Length)] = value;
80+
}
81+
}
82+
83+
private static string Normalize(string key) => key.Replace("__", ConfigurationPath.KeyDelimiter);
84+
}
85+
}

0 commit comments

Comments
 (0)