Skip to content

Implement "enahanced telemetry reporting" #7360

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

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public CompositeConfigurationSource(IEnumerable<IConfigurationSource> sources)
_sources = [..sources];
}

public ConfigurationOrigins Origin => ConfigurationOrigins.Unknown;

/// <summary>
/// Adds a new configuration source to this instance.
/// </summary>
Expand All @@ -51,50 +53,260 @@ public void Add(IConfigurationSource source)

/// <inheritdoc />
public ConfigurationResult<string> GetString(string key, IConfigurationTelemetry telemetry, Func<string, bool>? validator, bool recordValue)
=> _sources
.Select(source => source.GetString(key, telemetry, validator, recordValue))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<string>.NotFound());
{
Copy link
Contributor

Choose a reason for hiding this comment

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

The only difference in all these GetXXX is the value retrieving function, which could be a lambda, to avoid the n-plicated code

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, I've gone back and forth on the lambda thing. I extracted these to lambdas in ConfigurationBuilder and it makes everything seem that much more complicated, that I'm really not sure which is best. Add to that the fact that there's slightly different behaviour between each of the cases and it ends up really not being clear-cut which approach is better tbh.

// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
// We also have to keep track of whether the last value was the last _found_ value
// as we need to "restore" the telemetry if so.
var result = ConfigurationResult<string>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetString(key, telemetry, validator, recordValue);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.Result, recordValue, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<int> GetInt32(string key, IConfigurationTelemetry telemetry, Func<int, bool>? validator)
=> _sources
.Select(source => source.GetInt32(key, telemetry, validator))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<int>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<int>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetInt32(key, telemetry, validator);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.Result, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<double> GetDouble(string key, IConfigurationTelemetry telemetry, Func<double, bool>? validator)
=> _sources
.Select(source => source.GetDouble(key, telemetry, validator))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<double>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<double>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetDouble(key, telemetry, validator);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.Result, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<bool> GetBool(string key, IConfigurationTelemetry telemetry, Func<bool, bool>? validator)
=> _sources
.Select(source => source.GetBool(key, telemetry, validator))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<bool>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<bool>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetBool(key, telemetry, validator);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.Result, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<IDictionary<string, string>> GetDictionary(string key, IConfigurationTelemetry telemetry, Func<IDictionary<string, string>, bool>? validator)
=> _sources
.Select(source => source.GetDictionary(key, telemetry, validator))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<IDictionary<string, string>>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<IDictionary<string, string>>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetDictionary(key, telemetry, validator);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.TelemetryOverride ?? result.Result?.ToString(), recordValue: true, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<IDictionary<string, string>> GetDictionary(string key, IConfigurationTelemetry telemetry, Func<IDictionary<string, string>, bool>? validator, bool allowOptionalMappings, char separator)
=> _sources
.Select(source => source.GetDictionary(key, telemetry, validator, allowOptionalMappings, separator))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<IDictionary<string, string>>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<IDictionary<string, string>>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetDictionary(key, telemetry, validator, allowOptionalMappings, separator);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.TelemetryOverride ?? result.Result?.ToString(), recordValue: true, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<IDictionary<string, string>> GetDictionary(string key, IConfigurationTelemetry telemetry, Func<IDictionary<string, string>, bool>? validator, Func<string, IDictionary<string, string>> parser)
=> _sources
.Select(source => source.GetDictionary(key, telemetry, validator, parser))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<IDictionary<string, string>>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<IDictionary<string, string>>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetDictionary(key, telemetry, validator, parser);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.TelemetryOverride ?? result.Result?.ToString(), recordValue: true, origin);
}

return result;
}

/// <inheritdoc />
public ConfigurationResult<T> GetAs<T>(string key, IConfigurationTelemetry telemetry, Func<string, ParsingResult<T>> converter, Func<T, bool>? validator, bool recordValue)
=> _sources
.Select(source => source.GetAs<T>(key, telemetry, converter, validator, recordValue))
.FirstOrDefault(value => value.IsValid, ConfigurationResult<T>.NotFound());
{
// We iterate in reverse order, and keep the last successful value
// because we need to record the data for all the sources in telemetry
var result = ConfigurationResult<T>.NotFound();
var isLastFound = false;
var origin = ConfigurationOrigins.Unknown;
for (var i = _sources.Count - 1; i >= 0; i--)
{
var source = _sources[i];
var value = source.GetAs(key, telemetry, converter, validator, recordValue);
if (value.IsValid)
{
result = value;
isLastFound = true;
origin = source.Origin;
}
else if (value.IsPresent)
{
isLastFound = false;
}
}

if (result.IsValid && !isLastFound)
{
telemetry.Record(key, result.TelemetryOverride ?? result.Result?.ToString(), recordValue: true, origin);
}

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public DictionaryConfigurationSource(IReadOnlyDictionary<string, string> diction
_dictionary = dictionary;
}

internal override ConfigurationOrigins Origin => ConfigurationOrigins.Code;
public override ConfigurationOrigins Origin => ConfigurationOrigins.Code;

protected override string? GetString(string key)
{
Expand Down
Loading
Loading