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
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,33 @@ internal partial class ConfigurationKeys
/// </summary>
public const string EnabledResourceDetectorTemplate = "OTEL_DOTNET_AUTO_{0}_RESOURCE_DETECTOR_ENABLED";

/// <summary>
/// Configuration key template for resource attributes.
/// </summary>
public const string ResourceAttributes = "OTEL_RESOURCE_ATTRIBUTES";

/// <summary>
/// Configuration key for setting the service name.
/// </summary>
public const string ServiceName = "OTEL_SERVICE_NAME";

/// <summary>
/// Configuration keys for file based configuration.
/// </summary>
public static class FileBasedConfiguration
{
/// <summary>
/// Configuration key for enabling file based configuration.
/// </summary>
public const string Enabled = "OTEL_EXPERIMENTAL_FILE_BASED_CONFIGURATION_ENABLED";

/// <summary>
/// Configuration key for the path to the configuration file.
/// Default is <c>"config.yaml"</c>.
/// </summary>
public const string FileName = "OTEL_EXPERIMENTAL_CONFIG_FILE";
}

/// <summary>
/// Configuration keys for traces.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ internal class FailFastSettings : Settings
{
public bool FailFast { get; private set; }

protected override void OnLoad(Configuration configuration)
protected override void OnLoadEnvVar(Configuration configuration)
{
FailFast = configuration.GetBool(ConfigurationKeys.FailFast) ?? false;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Reflection;
using Vendors.YamlDotNet.Core;
using Vendors.YamlDotNet.Core.Events;
using Vendors.YamlDotNet.Serialization;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,4 @@
namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration.Parser;

[AttributeUsage(AttributeTargets.Class)]
internal sealed class EmptyObjectOnEmptyYamlAttribute : Attribute
{
}
internal sealed class EmptyObjectOnEmptyYamlAttribute : Attribute;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Vendors.YamlDotNet.Serialization;
using Vendors.YamlDotNet.Serialization.NodeDeserializers;

namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration.Parser;

internal static class Parser
{
public static YamlConfiguration ParseYaml(string filePath)
{
var deserializer = new DeserializerBuilder()
.WithNodeDeserializer(existing => new ConditionalDeserializer(existing), s => s.InsteadOf<NullNodeDeserializer>())
.WithTypeConverter(new EnvVarTypeConverter())
.IgnoreUnmatchedProperties()
.Build();

var yaml = File.ReadAllText(filePath);
var config = deserializer.Deserialize<YamlConfiguration>(yaml);
return config;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Vendors.YamlDotNet.Serialization;

namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;

internal class ResourceAttribute
{
/// <summary>
/// Gets or sets the name of the resource attribute.
/// </summary>
[YamlMember(Alias = "name")]
public string Name { get; set; } = null!;

/// <summary>
/// Gets or sets the value of the resource attribute.
/// </summary>
[YamlMember(Alias = "value")]
public object Value { get; set; } = null!;

/// <summary>
/// Gets or sets the type of the resource attribute.
/// </summary>
[YamlMember(Alias = "type")]
public string Type { get; set; } = "string";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Vendors.YamlDotNet.Serialization;

namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;

internal class ResourceConfiguration
{
/// <summary>
/// Gets or sets the list of resource attributes.
/// </summary>
[YamlMember(Alias = "attributes")]
public List<ResourceAttribute>? Attributes { get; set; }

/// <summary>
/// Gets or sets the attributes list for the resource.
/// </summary>
[YamlMember(Alias = "attributes_list")]
public string? AttributesList { get; set; }

public List<KeyValuePair<string, object>> ParseAttributes()
{
var resourceAttributesWithPriority = new Dictionary<string, object>();

if (Attributes != null)
{
foreach (var attr in Attributes)
{
if (!resourceAttributesWithPriority.ContainsKey(attr.Name))
{
// TODO parse type and converting the value accordingly.
resourceAttributesWithPriority.Add(attr.Name, attr.Value);
}
}
}

if (AttributesList != null)
{
const char attributeListSplitter = ',';
char[] attributeKeyValueSplitter = ['='];

var rawAttributes = AttributesList.Split(attributeListSplitter);
foreach (var rawKeyValuePair in rawAttributes)
{
var keyValuePair = rawKeyValuePair.Split(attributeKeyValueSplitter, 2);
if (keyValuePair.Length != 2)
{
continue;
}

var key = keyValuePair[0].Trim();

if (!resourceAttributesWithPriority.ContainsKey(key))
{
resourceAttributesWithPriority.Add(key, keyValuePair[1].Trim());
}
}
}

return resourceAttributesWithPriority.ToList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Vendors.YamlDotNet.Serialization;

namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;

internal class YamlConfiguration
{
/// <summary>
/// Gets or sets the file format version.
/// The yaml format is documented at
/// https://github.com/open-telemetry/opentelemetry-configuration/tree/main/schema
/// </summary>
[YamlMember(Alias = "file_format")]
public string? FileFormat { get; set; }

/// <summary>
/// Gets or sets the resource configuration.
/// Configure resource for all signals.
/// If omitted, the default resource is used.
/// </summary>
[YamlMember(Alias = "resource")]
public ResourceConfiguration? Resource { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@ internal class GeneralSettings : Settings
/// </summary>
public IList<string> Plugins { get; } = new List<string>();

/// <summary>
/// Gets the list of enabled resource detectors.
/// </summary>
public IReadOnlyList<ResourceDetector> EnabledResourceDetectors { get; private set; } = new List<ResourceDetector>();

/// <summary>
/// Gets a value indicating whether the <see cref="AppDomain.UnhandledException"/> event should trigger
/// the flushing of telemetry data.
Expand All @@ -32,7 +27,7 @@ internal class GeneralSettings : Settings
/// </summary>
public bool ProfilerEnabled { get; private set; }

protected override void OnLoad(Configuration configuration)
protected override void OnLoadEnvVar(Configuration configuration)
{
var providerPlugins = configuration.GetString(ConfigurationKeys.ProviderPlugins);
if (providerPlugins != null)
Expand All @@ -43,12 +38,6 @@ protected override void OnLoad(Configuration configuration)
}
}

var resourceDetectorsEnabledByDefault = configuration.GetBool(ConfigurationKeys.ResourceDetectorEnabled) ?? true;

EnabledResourceDetectors = configuration.ParseEnabledEnumList<ResourceDetector>(
enabledByDefault: resourceDetectorsEnabledByDefault,
enabledConfigurationTemplate: ConfigurationKeys.EnabledResourceDetectorTemplate);

FlushOnUnhandledException = configuration.GetBool(ConfigurationKeys.FlushOnUnhandledException) ?? false;
SetupSdk = configuration.GetBool(ConfigurationKeys.SetupSdk) ?? true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ internal class LogSettings : Settings
/// </summary>
public OtlpSettings? OtlpSettings { get; private set; }

protected override void OnLoad(Configuration configuration)
protected override void OnLoadEnvVar(Configuration configuration)
{
LogsEnabled = configuration.GetBool(ConfigurationKeys.Logs.LogsEnabled) ?? true;
LogExporters = ParseLogExporter(configuration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ internal class MetricSettings : Settings
/// </summary>
public OtlpSettings? OtlpSettings { get; private set; }

protected override void OnLoad(Configuration configuration)
protected override void OnLoadEnvVar(Configuration configuration)
{
MetricExporters = ParseMetricExporter(configuration);
if (MetricExporters.Contains(MetricsExporter.Otlp))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,24 @@ namespace OpenTelemetry.AutoInstrumentation.Configurations;

internal static class ResourceConfigurator
{
internal const string ServiceNameAttribute = "service.name";

public static ResourceBuilder CreateResourceBuilder(IReadOnlyList<ResourceDetector> enabledResourceDetectors)
public static ResourceBuilder CreateResourceBuilder(ResourceSettings resourceSettings)
{
var resourceBuilder = ResourceBuilder
.CreateEmpty() // Don't use CreateDefault because it puts service name unknown by default.
.AddEnvironmentVariableDetector()
.AddTelemetrySdk()
.AddAttributes(new KeyValuePair<string, object>[]
{
.CreateEmpty(); // Don't use CreateDefault because it puts service name unknown by default.

if (resourceSettings.EnvironmentalVariablesDetectorEnabled)
{
resourceBuilder.AddEnvironmentVariableDetector();
}

resourceBuilder.AddTelemetrySdk()
.AddAttributes([
new(Constants.DistributionAttributes.TelemetryDistroNameAttributeName, Constants.DistributionAttributes.TelemetryDistroNameAttributeValue),
new(Constants.DistributionAttributes.TelemetryDistroVersionAttributeName, AutoInstrumentationVersion.Version)
});
])
.AddAttributes(resourceSettings.Resources);

foreach (var enabledResourceDetector in enabledResourceDetectors)
foreach (var enabledResourceDetector in resourceSettings.EnabledDetectors)
{
resourceBuilder = enabledResourceDetector switch
{
Expand All @@ -39,10 +42,10 @@ public static ResourceBuilder CreateResourceBuilder(IReadOnlyList<ResourceDetect
}

var resource = resourceBuilder.Build();
if (!resource.Attributes.Any(kvp => kvp.Key == ServiceNameAttribute))
if (resource.Attributes.All(kvp => kvp.Key != Constants.ResourceAttributes.AttributeServiceName))
{
// service.name was not configured yet use the fallback.
resourceBuilder.AddAttributes(new KeyValuePair<string, object>[] { new(ServiceNameAttribute, ServiceNameConfigurator.GetFallbackServiceName()) });
resourceBuilder.AddAttributes([new(Constants.ResourceAttributes.AttributeServiceName, ServiceNameConfigurator.GetFallbackServiceName())]);
}

var pluginManager = Instrumentation.PluginManager;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;

namespace OpenTelemetry.AutoInstrumentation.Configurations;

internal class ResourceSettings : Settings
{
/// <summary>
/// Gets or sets the list of enabled resource detectors.
/// </summary>
public IReadOnlyList<ResourceDetector> EnabledDetectors { get; set; } = [];

/// <summary>
/// Gets or sets the list of enabled resources.
/// </summary>
public IReadOnlyList<KeyValuePair<string, object>> Resources { get; set; } = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

for the future, may want to use union ref struct not to cause object boxing for simple types.


/// <summary>
/// Gets or sets a value indicating whether environmental variables resource detector is enabled.
/// </summary>
public bool EnvironmentalVariablesDetectorEnabled { get; set; } = true;

protected override void OnLoadEnvVar(Configuration configuration)
{
var resourceDetectorsEnabledByDefault = configuration.GetBool(ConfigurationKeys.ResourceDetectorEnabled) ?? true;

EnabledDetectors = configuration.ParseEnabledEnumList<ResourceDetector>(
enabledByDefault: resourceDetectorsEnabledByDefault,
enabledConfigurationTemplate: ConfigurationKeys.EnabledResourceDetectorTemplate);
}

protected override void OnLoadFile(YamlConfiguration configuration)
{
EnvironmentalVariablesDetectorEnabled = false;

Resources = configuration.Resource?.ParseAttributes() ?? [];

// TODO initialize EnabledDetectors from file configuration
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using System.Diagnostics.CodeAnalysis;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.Configurations;
Expand All @@ -18,7 +17,7 @@ internal class SdkSettings : Settings
/// </summary>
public IList<Propagator> Propagators { get; private set; } = new List<Propagator>();

protected override void OnLoad(Configuration configuration)
protected override void OnLoadEnvVar(Configuration configuration)
{
Propagators = ParsePropagator(configuration);
}
Expand Down
Loading
Loading