Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
21 changes: 21 additions & 0 deletions docs/file-based-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,27 @@ For more details, see: [OpenTelemetry YAML File Format Specification](https://gi

## Configuration Examples

### Propagator Configuration

You can configure text map context propagators directly in YAML or via the
`OTEL_PROPAGATORS` environment variable.
For more details and updates, see: [Propagators list and documentation](config.md/#propagators)
To disable a propagator, comment out or remove its corresponding entry.

``` yaml
# If no propagators are specified, none will be added automatically.
propagator:
# Composite propagators are evaluated together.
# Entries from .composite_list are appended here (duplicates are filtered out).
composite:
tracecontext: # W3C Trace Context propagator
baggage: # W3C Baggage propagator
b3: # B3 single-header propagator
b3multi: # B3 multi-header propagator
# Alternatively, configure via a comma-separated list (same format as OTEL_PROPAGATORS).
composite_list: ${OTEL_PROPAGATORS}
```

### Resource Configuration

You can configure resource attributes directly in YAML or via the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static void UseEnvironmentVariables(SdkSettings settings)
SetSdkTextMapPropagator(settings.Propagators);
}

private static void SetSdkTextMapPropagator(IList<Propagator> settingsPropagators)
private static void SetSdkTextMapPropagator(IReadOnlyList<Propagator> settingsPropagators)
{
if (settingsPropagators.Count == 0)
{
Expand Down Expand Up @@ -43,18 +43,13 @@ private static void SetSdkTextMapPropagator(IList<Propagator> settingsPropagator

private static TextMapPropagator GetTextMapPropagator(Propagator propagator)
{
switch (propagator)
return propagator switch
{
case Propagator.W3CTraceContext:
return new TraceContextPropagator();
case Propagator.W3CBaggage:
return new BaggagePropagator();
case Propagator.B3Multi:
return new Extensions.Propagators.B3Propagator(singleHeader: false);
case Propagator.B3Single:
return new Extensions.Propagators.B3Propagator(singleHeader: true);
}

throw new ArgumentOutOfRangeException(nameof(propagator), propagator, "Propagator has an unexpected value.");
Propagator.W3CTraceContext => new TraceContextPropagator(),
Propagator.W3CBaggage => new BaggagePropagator(),
Propagator.B3Multi => new Extensions.Propagators.B3Propagator(singleHeader: false),
Propagator.B3Single => new Extensions.Propagators.B3Propagator(singleHeader: true),
_ => throw new ArgumentOutOfRangeException(nameof(propagator), propagator, "Propagator has an unexpected value."),
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Vendors.YamlDotNet.Serialization;

namespace OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;

internal class PropagatorConfiguration
{
/// <summary>
/// Gets or sets the composite propagator configuration.
/// </summary>
[YamlMember(Alias = "composite")]
public Dictionary<string, object>? Composite { get; set; }

/// <summary>
/// Gets or sets the composite list for the propagator.
/// </summary>
[YamlMember(Alias = "composite_list")]
public string? CompositeList { get; set; }

public IReadOnlyList<Propagator> GetEnabledPropagators()
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. Distinct() already does the HashSet logic for you, no need to be explicit.

  2. return early >

if (Composite is null && string.IsNullOrEmpty(CompositeList))
{
    return Array.Empty<Propagator>();
}
  1. ToLowerInvariant() adds extra string allocation. Maybe you can reuse StringComparison.InvariantCultureIgnoreCase based logic.

  2. Try to verify the list and not to copy it's contents over to another.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed in a19d41f

ToLowerInvariant() adds extra string allocation. Maybe you can reuse StringComparison.InvariantCultureIgnoreCase based logic.

I made it case-sensitive, as it was done in OTEL_PROPAGATORS.

{
if (Composite is null && string.IsNullOrEmpty(CompositeList))
{
return [];
}

var propagatorNames = (Composite?.Keys ?? Enumerable.Empty<string>())
.Concat(!string.IsNullOrEmpty(CompositeList)
? CompositeList!.Split(Constants.ConfigurationValues.Separator)
: [])
.Distinct();

var propagators = propagatorNames
.Select<string, Propagator?>(name => name switch
{
Constants.ConfigurationValues.Propagators.W3CTraceContext => Propagator.W3CTraceContext,
Constants.ConfigurationValues.Propagators.W3CBaggage => Propagator.W3CBaggage,
Constants.ConfigurationValues.Propagators.B3Multi => Propagator.B3Multi,
Constants.ConfigurationValues.Propagators.B3Single => Propagator.B3Single,
_ => null
Copy link
Contributor

Choose a reason for hiding this comment

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

is this legal? what is the result, NoOpPropagator etc?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it is legal.
Added a test for the Noop Propagator 62af6ff

})
.OfType<Propagator>()
.ToList();

return propagators;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,11 @@ internal class YamlConfiguration
/// </summary>
[YamlMember(Alias = "resource")]
public ResourceConfiguration? Resource { get; set; }

/// <summary>
/// Gets or sets the text map context propagator configuration.
/// If omitted, a noop propagator is used.
/// </summary>
[YamlMember(Alias = "propagator")]
public PropagatorConfiguration? Propagator { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
using OpenTelemetry.AutoInstrumentation.Logging;

namespace OpenTelemetry.AutoInstrumentation.Configurations;
Expand All @@ -15,14 +16,19 @@ internal class SdkSettings : Settings
/// <summary>
/// Gets the list of propagators to be used.
/// </summary>
public IList<Propagator> Propagators { get; private set; } = new List<Propagator>();
public IReadOnlyList<Propagator> Propagators { get; private set; } = [];

protected override void OnLoadEnvVar(Configuration configuration)
{
Propagators = ParsePropagator(configuration);
}

private static IList<Propagator> ParsePropagator(Configuration configuration)
protected override void OnLoadFile(YamlConfiguration configuration)
{
Propagators = configuration.Propagator?.GetEnabledPropagators() ?? [];
}

private static List<Propagator> ParsePropagator(Configuration configuration)
{
var propagatorEnvVar = configuration.GetString(ConfigurationKeys.Sdk.Propagators);
var propagators = new List<Propagator>();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using OpenTelemetry.AutoInstrumentation.Configurations;
using OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration;
using Xunit;

namespace OpenTelemetry.AutoInstrumentation.Tests.Configurations.FileBased;

public class FilebasedSdkSettingsTests
{
[Fact]
public void LoadFile_CompositeOnlyPropagators()
{
var propagator = new PropagatorConfiguration
{
Composite = new Dictionary<string, object>
{
{ "tracecontext", new object() },
{ "baggage", new object() }
}
};

var conf = new YamlConfiguration { Propagator = propagator };
var settings = new SdkSettings();

settings.LoadFile(conf);

Assert.Equal(2, settings.Propagators.Count);
Assert.Contains(Propagator.W3CTraceContext, settings.Propagators);
Assert.Contains(Propagator.W3CBaggage, settings.Propagators);
}

[Fact]
public void LoadFile_CompositeListOnlyPropagators()
{
var propagator = new PropagatorConfiguration
{
CompositeList = "b3multi,b3"
};

var conf = new YamlConfiguration { Propagator = propagator };
var settings = new SdkSettings();

settings.LoadFile(conf);

Assert.Equal(2, settings.Propagators.Count);
Assert.Contains(Propagator.B3Multi, settings.Propagators);
Assert.Contains(Propagator.B3Single, settings.Propagators);
}

[Fact]
public void LoadFile_CompositeAndCompositeList_AreMergedWithoutDuplicates()
{
var propagator = new PropagatorConfiguration
{
Composite = new Dictionary<string, object>
{
{ "tracecontext", new object() },
{ "baggage", new object() }
},
CompositeList = "tracecontext,b3"
};

var conf = new YamlConfiguration { Propagator = propagator };
var settings = new SdkSettings();

settings.LoadFile(conf);

Assert.Equal(3, settings.Propagators.Count);
Assert.Contains(Propagator.W3CTraceContext, settings.Propagators);
Assert.Contains(Propagator.W3CBaggage, settings.Propagators);
Assert.Contains(Propagator.B3Single, settings.Propagators);
}

[Fact]
public void GetEnabledPropagators_UnknownValues_AreIgnored()
{
var config = new PropagatorConfiguration
{
CompositeList = "invalid,b3multi"
Copy link
Contributor

Choose a reason for hiding this comment

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

Empty test here?

Suggested change
CompositeList = "invalid,b3multi"
CompositeList = "invalid,b3multi,"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored test with load to settings 62af6ff

};

var result = config.GetEnabledPropagators();

Assert.Single(result);
Assert.Equal(Propagator.B3Multi, result[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
file_format: "1.0-rc.1"

propagator:
composite:
tracecontext:
baggage:
b3:
b3multi:

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
file_format: "1.0-rc.1"

propagator:
composite_list: ${OTEL_PROPAGATORS}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

using Xunit;
using YamlParser = OpenTelemetry.AutoInstrumentation.Configurations.FileBasedConfiguration.Parser.Parser;

namespace OpenTelemetry.AutoInstrumentation.Tests.Configurations.FileBased.Parser;

[Collection("Non-Parallel Collection")]
public class ParserPropagatorTests
{
[Fact]
public void Parse_FullConfigYaml_ShouldPopulateModelCorrectly()
{
var config = YamlParser.ParseYaml("Configurations/FileBased/Files/TestPropagatorFile.yaml");

Assert.NotNull(config);
Assert.NotNull(config.Propagator);
Assert.NotNull(config.Propagator.Composite);
var composite = config.Propagator.Composite;
Assert.Null(config.Propagator.CompositeList);

string[] expectedPropagators = [
"tracecontext", "baggage", "b3", "b3multi",
];

foreach (var expected in expectedPropagators)
{
Assert.Contains(expected, composite.Keys);
}
}

[Fact]
public void Parse_EnvVarYaml_ShouldPopulateModelCompletely()
{
Environment.SetEnvironmentVariable("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi");

var config = YamlParser.ParseYaml("Configurations/FileBased/Files/TestPropagatorFileEnvVars.yaml");

Assert.NotNull(config);
Assert.NotNull(config.Propagator);
Assert.NotNull(config.Propagator.CompositeList);
Assert.Null(config.Propagator.Composite);
Assert.Equal("tracecontext,baggage,b3,b3multi", config.Propagator.CompositeList);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,15 @@
</ItemGroup>

<ItemGroup>
<None Update="Configurations\FileBased\Files\TestPropagatorFile.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Configurations\FileBased\Files\TestResourceFile.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Configurations\FileBased\Files\TestPropagatorFileEnvVars.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Configurations\FileBased\Files\TestResourceFileEnvVars.yaml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
Expand Down
Loading