-
Notifications
You must be signed in to change notification settings - Fork 772
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SDK + Jaeger] Support loading environment variables from IConfiguration in Traces & Metrics #3720
Changes from all commits
81cc629
d4ccabf
1405478
b20705e
df5b8d3
142dbd2
305cfe5
cff5bc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,42 @@ | ||||||
// <copyright file="ProviderBuilderServiceCollectionExtensions.cs" company="OpenTelemetry Authors"> | ||||||
// Copyright The 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. | ||||||
// </copyright> | ||||||
|
||||||
#nullable enable | ||||||
|
||||||
using System.Diagnostics; | ||||||
using Microsoft.Extensions.Configuration; | ||||||
using Microsoft.Extensions.DependencyInjection.Extensions; | ||||||
|
||||||
namespace Microsoft.Extensions.DependencyInjection; | ||||||
|
||||||
internal static class ProviderBuilderServiceCollectionExtensions | ||||||
{ | ||||||
public static IServiceCollection AddOpenTelemetryProviderBuilderServices(this IServiceCollection services) | ||||||
{ | ||||||
Debug.Assert(services != null, "services was null"); | ||||||
|
||||||
services.AddOptions(); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No warning from the missing null forgiving operator?
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class is internal and |
||||||
|
||||||
// Note: When using a host builder IConfiguration is automatically | ||||||
// registered and this registration will no-op. This only runs for | ||||||
// Sdk.Create* style or when manually creating a ServiceCollection. The | ||||||
// point of this registration is to make IConfiguration available in | ||||||
// those cases. | ||||||
services!.TryAddSingleton<IConfiguration>(sp => new ConfigurationBuilder().AddEnvironmentVariables().Build()); | ||||||
|
||||||
return services!; | ||||||
} | ||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
// <copyright file="ConfigurationExtensions.cs" company="OpenTelemetry Authors"> | ||
// Copyright The 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. | ||
// </copyright> | ||
|
||
#nullable enable | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
#if !NETFRAMEWORK && !NETSTANDARD2_0 | ||
using System.Diagnostics.CodeAnalysis; | ||
#endif | ||
using System.Globalization; | ||
using Microsoft.Extensions.Configuration; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.DependencyInjection.Extensions; | ||
using Microsoft.Extensions.Options; | ||
|
||
namespace OpenTelemetry.Internal; | ||
|
||
internal static class ConfigurationExtensions | ||
{ | ||
public delegate bool TryParseFunc<T>( | ||
string value, | ||
#if !NETFRAMEWORK && !NETSTANDARD2_0 | ||
[NotNullWhen(true)] | ||
#endif | ||
out T? parsedValue); | ||
|
||
public static bool TryGetStringValue( | ||
this IConfiguration configuration, | ||
string key, | ||
#if !NETFRAMEWORK && !NETSTANDARD2_0 | ||
[NotNullWhen(true)] | ||
#endif | ||
out string? value) | ||
{ | ||
value = configuration.GetValue<string?>(key, null); | ||
|
||
return !string.IsNullOrWhiteSpace(value); | ||
} | ||
|
||
public static bool TryGetUriValue( | ||
this IConfiguration configuration, | ||
string key, | ||
#if !NETFRAMEWORK && !NETSTANDARD2_0 | ||
[NotNullWhen(true)] | ||
#endif | ||
out Uri? value) | ||
{ | ||
if (!configuration.TryGetStringValue(key, out var stringValue)) | ||
{ | ||
value = null; | ||
return false; | ||
} | ||
|
||
if (!Uri.TryCreate(stringValue, UriKind.Absolute, out value)) | ||
{ | ||
throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just a bug reminder #3690 😉 Of course, it can (and should) be addressed in a separate issue. Feel free to resolve this comment. |
||
} | ||
|
||
return true; | ||
} | ||
|
||
public static bool TryGetIntValue( | ||
this IConfiguration configuration, | ||
string key, | ||
out int value) | ||
{ | ||
if (!configuration.TryGetStringValue(key, out var stringValue)) | ||
{ | ||
value = default; | ||
return false; | ||
} | ||
|
||
if (!int.TryParse(stringValue, NumberStyles.None, CultureInfo.InvariantCulture, out value)) | ||
{ | ||
throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'"); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public static bool TryGetValue<T>( | ||
this IConfiguration configuration, | ||
string key, | ||
TryParseFunc<T> tryParseFunc, | ||
#if !NETFRAMEWORK && !NETSTANDARD2_0 | ||
[NotNullWhen(true)] | ||
#endif | ||
out T? value) | ||
{ | ||
if (!configuration.TryGetStringValue(key, out var stringValue)) | ||
{ | ||
value = default; | ||
return false; | ||
} | ||
|
||
if (!tryParseFunc(stringValue!, out value)) | ||
{ | ||
throw new FormatException($"{key} environment variable has an invalid value: '{stringValue}'"); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public static IServiceCollection RegisterOptionsFactory<T>( | ||
this IServiceCollection services, | ||
Func<IConfiguration, T> optionsFactoryFunc) | ||
where T : class | ||
{ | ||
Debug.Assert(services != null, "services was null"); | ||
Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); | ||
|
||
services!.TryAddSingleton<IOptionsFactory<T>>(sp => | ||
{ | ||
return new DelegatingOptionsFactory<T>( | ||
optionsFactoryFunc!, | ||
sp.GetRequiredService<IConfiguration>(), | ||
sp.GetServices<IConfigureOptions<T>>(), | ||
sp.GetServices<IPostConfigureOptions<T>>(), | ||
sp.GetServices<IValidateOptions<T>>()); | ||
}); | ||
|
||
return services!; | ||
} | ||
|
||
private sealed class DelegatingOptionsFactory<T> : OptionsFactory<T> | ||
where T : class | ||
{ | ||
private readonly Func<IConfiguration, T> optionsFactoryFunc; | ||
private readonly IConfiguration configuration; | ||
|
||
public DelegatingOptionsFactory( | ||
Func<IConfiguration, T> optionsFactoryFunc, | ||
IConfiguration configuration, | ||
IEnumerable<IConfigureOptions<T>> setups, | ||
IEnumerable<IPostConfigureOptions<T>> postConfigures, | ||
IEnumerable<IValidateOptions<T>> validations) | ||
: base(setups, postConfigures, validations) | ||
{ | ||
Debug.Assert(optionsFactoryFunc != null, "optionsFactoryFunc was null"); | ||
Debug.Assert(configuration != null, "configuration was null"); | ||
|
||
this.optionsFactoryFunc = optionsFactoryFunc!; | ||
this.configuration = configuration!; | ||
} | ||
|
||
protected override T CreateInstance(string name) | ||
=> this.optionsFactoryFunc(this.configuration); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes me wonder what the harm would be in bumping all the extension packages to
[5.0.0,)
?Just poking around the dependencies of the Microsoft.Extensions.* packages themselves seems to suggest they're always bumped in unison.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an issue with that. I'm not going to do it on this PR but we could bring it up on SIG?