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
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This project follows semantic versioning. Release tags use `vMAJOR.MINOR.PATCH`.

## [Unreleased]

No unreleased changes.
- Changed `OtlpOptions.Protocol` from a string to the nullable OpenTelemetry `OtlpExportProtocol` enum.

## [1.0.0] - 2026-05-24

Expand Down
112 changes: 58 additions & 54 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,54 +1,58 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup Label="Versioning + SourceLink (library-side)">
<PackageVersion Include="Atya.Governance.CodeQuality" Version="1.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.300" />
<PackageVersion Include="MinVer" Version="7.0.0" />
</ItemGroup>
<ItemGroup Label="Testing">
<PackageVersion Include="Atya.Governance.Testing" Version="1.0.0" />
<PackageVersion Include="Castle.Core" Version="5.2.1" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="coverlet.msbuild" Version="10.0.1" />
<PackageVersion Include="FluentAssertions" Version="8.10.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.analyzers" Version="1.27.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>
<ItemGroup Label="Benchmarking">
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
</ItemGroup>
<ItemGroup Label="Runtime + integrations">
<PackageVersion Include="Atya.Diagnostics.Observation" Version="1.0.0" />
<PackageVersion Include="Atya.Foundation.Guards" Version="1.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.8" />
<PackageVersion Include="OpenTelemetry" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.15.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.15.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.15.2" />
</ItemGroup>
</Project>
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>

<ItemGroup Label="Versioning + SourceLink (library-side)">
<PackageVersion Include="Atya.Governance.CodeQuality" Version="1.0.0" />
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="10.0.300" />
<PackageVersion Include="MinVer" Version="7.0.0" />
</ItemGroup>

<ItemGroup Label="Testing">
<PackageVersion Include="Atya.Governance.Testing" Version="1.0.0" />
<PackageVersion Include="Castle.Core" Version="5.2.1" />
<PackageVersion Include="coverlet.collector" Version="10.0.1" />
<PackageVersion Include="coverlet.msbuild" Version="10.0.1" />
<PackageVersion Include="FluentAssertions" Version="8.10.0" />
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.8" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
<PackageVersion Include="NSubstitute" Version="5.3.0" />
<PackageVersion Include="NSubstitute.Analyzers.CSharp" Version="1.0.17" />
<PackageVersion Include="xunit" Version="2.9.3" />
<PackageVersion Include="xunit.analyzers" Version="1.27.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
</ItemGroup>

<ItemGroup Label="Benchmarking">
<PackageVersion Include="BenchmarkDotNet" Version="0.15.8" />
</ItemGroup>

<ItemGroup Label="Runtime + integrations">
<PackageVersion Include="Atya.Diagnostics.Observation" Version="1.0.0" />
<PackageVersion Include="Atya.Foundation.Guards" Version="1.0.0" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Diagnostics.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.FileProviders.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Logging.Configuration" Version="10.0.8" />
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.8" />
<PackageVersion Include="OpenTelemetry" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Extensions.Hosting" Version="1.15.3" />
<PackageVersion Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.15.2" />
<PackageVersion Include="OpenTelemetry.Instrumentation.EntityFrameworkCore" Version="1.15.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.GrpcNetClient" Version="1.15.1-beta.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Http" Version="1.15.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.Runtime" Version="1.15.1" />
<PackageVersion Include="OpenTelemetry.Instrumentation.SqlClient" Version="1.15.2" />
</ItemGroup>
</Project>
3 changes: 2 additions & 1 deletion benchmarks/OpenTelemetry.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using BenchmarkDotNet.Order;
using BenchmarkDotNet.Running;
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter;

namespace OpenTelemetry.Benchmarks;

Expand Down Expand Up @@ -88,7 +89,7 @@ private static void ConfigureFull(OpenTelemetryOptions options)
options.Instrumentations.Runtime.Enabled = true;
options.Exporters.Otlp.Enabled = true;
options.Exporters.Otlp.Endpoint = "http://localhost:4317";
options.Exporters.Otlp.Protocol = "grpc";
options.Exporters.Otlp.Protocol = OtlpExportProtocol.Grpc;
options.Exporters.Otlp.Headers["x-benchmark"] = "opentelemetry";
}
}
6 changes: 4 additions & 2 deletions src/OpenTelemetry/Internal/OpenTelemetryOptionsValidator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Atya.Diagnostics.OpenTelemetry.Options;
using Atya.Foundation.Guards;
using Microsoft.Extensions.Options;
using OpenTelemetry.Exporter;

namespace Atya.Diagnostics.OpenTelemetry.Internal;

Expand Down Expand Up @@ -43,10 +44,11 @@ public ValidateOptionsResult Validate(string? name, OpenTelemetryOptions options
$"OpenTelemetryOptions.Exporters.Otlp.Endpoint '{options.Exporters.Otlp.Endpoint}' is not a valid absolute URI.");
}

if (!OtlpExporterConfigurator.IsSupportedProtocol(options.Exporters.Otlp.Protocol))
if (options.Exporters.Otlp.Protocol is { } protocol &&
!Enum.IsDefined(typeof(OtlpExportProtocol), protocol))
{
return ValidateOptionsResult.Fail(
"OpenTelemetryOptions.Exporters.Otlp.Protocol must be either 'grpc' or 'http/protobuf'.");
"OpenTelemetryOptions.Exporters.Otlp.Protocol must be a defined OtlpExportProtocol value.");
}

foreach (var header in options.Exporters.Otlp.Headers)
Expand Down
41 changes: 10 additions & 31 deletions src/OpenTelemetry/Internal/OtlpExporterConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,17 @@ public static void Apply(OtlpExporterOptions otlp, OtlpOptions options)
otlp.Endpoint = new Uri(options.Endpoint);
}

if (!string.IsNullOrWhiteSpace(options.Protocol))
if (options.Protocol is { } protocol)
{
otlp.Protocol = ParseProtocol(options.Protocol);
if (!Enum.IsDefined(typeof(OtlpExportProtocol), protocol))
{
throw new ArgumentOutOfRangeException(
nameof(options),
protocol,
"OTLP protocol must be a defined OtlpExportProtocol value.");
}

otlp.Protocol = protocol;
}

if (options.Headers.Count > 0)
Expand All @@ -34,33 +42,4 @@ public static void Apply(OtlpExporterOptions otlp, OtlpOptions options)
}
}

public static bool IsSupportedProtocol(string? protocol)
{
if (string.IsNullOrWhiteSpace(protocol))
{
return true;
}

return protocol.Equals("grpc", StringComparison.OrdinalIgnoreCase) ||
protocol.Equals("http/protobuf", StringComparison.OrdinalIgnoreCase);
}

private static OtlpExportProtocol ParseProtocol(string protocol)
{
var normalizedProtocol = Guard.AgainstNullOrWhiteSpace(protocol).Trim();

if (normalizedProtocol.Equals("grpc", StringComparison.OrdinalIgnoreCase))
{
return OtlpExportProtocol.Grpc;
}

if (normalizedProtocol.Equals("http/protobuf", StringComparison.OrdinalIgnoreCase))
{
return OtlpExportProtocol.HttpProtobuf;
}

throw new ArgumentException(
"OTLP protocol must be either 'grpc' or 'http/protobuf'.",
nameof(protocol));
}
}
6 changes: 4 additions & 2 deletions src/OpenTelemetry/Options/OtlpOptions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// <copyright file="OtlpOptions.cs" company="Atya">
// Copyright (c) Atya. All rights reserved.
// </copyright>
using OpenTelemetry.Exporter;

namespace Atya.Diagnostics.OpenTelemetry.Options;

/// <summary>
Expand All @@ -20,10 +22,10 @@ public sealed class OtlpOptions
public string? Endpoint { get; set; }

/// <summary>
/// Gets or sets the OTLP transport protocol. Supported values: "grpc", "http/protobuf".
/// Gets or sets the OTLP transport protocol.
/// When null, the OpenTelemetry SDK default is used.
/// </summary>
public string? Protocol { get; set; }
public OtlpExportProtocol? Protocol { get; set; }

/// <summary>
/// Gets additional headers to include in OTLP export requests.
Expand Down
2 changes: 1 addition & 1 deletion src/OpenTelemetry/PublicAPI.Shipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Endpoint.get -> string?
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Endpoint.set -> void
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Headers.get -> System.Collections.Generic.IDictionary<string!, string!>!
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.OtlpOptions() -> void
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Protocol.get -> string?
*REMOVED*Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Protocol.get -> string?
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Protocol.set -> void
static Microsoft.Extensions.DependencyInjection.OpenTelemetryServiceCollectionExtensions.AddAtyaOpenTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, Microsoft.Extensions.Configuration.IConfiguration! configuration, string! sectionName = "OpenTelemetry") -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
static Microsoft.Extensions.DependencyInjection.OpenTelemetryServiceCollectionExtensions.AddAtyaOpenTelemetry(this Microsoft.Extensions.DependencyInjection.IServiceCollection! services, System.Action<Atya.Diagnostics.OpenTelemetry.Options.OpenTelemetryOptions!>? configure = null) -> Microsoft.Extensions.DependencyInjection.IServiceCollection!
1 change: 1 addition & 0 deletions src/OpenTelemetry/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
#nullable enable
Atya.Diagnostics.OpenTelemetry.Options.OtlpOptions.Protocol.get -> OpenTelemetry.Exporter.OtlpExportProtocol?
7 changes: 4 additions & 3 deletions src/OpenTelemetry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dotnet add package Atya.Diagnostics.OpenTelemetry

```csharp
using Microsoft.Extensions.DependencyInjection;
using OpenTelemetry.Exporter;

services.AddAtyaOpenTelemetry(options =>
{
Expand All @@ -38,7 +39,7 @@ services.AddAtyaOpenTelemetry(options =>

options.Exporters.Otlp.Enabled = true;
options.Exporters.Otlp.Endpoint = "http://otel-collector:4317";
options.Exporters.Otlp.Protocol = "grpc";
options.Exporters.Otlp.Protocol = OtlpExportProtocol.Grpc;
});
```

Expand Down Expand Up @@ -81,7 +82,7 @@ Bind from the default `OpenTelemetry` configuration section:
"Otlp": {
"Enabled": true,
"Endpoint": "http://otel-collector:4317",
"Protocol": "grpc",
"Protocol": "Grpc",
"Headers": {
"x-service": "orders"
}
Expand Down Expand Up @@ -124,7 +125,7 @@ Options are validated through `Microsoft.Extensions.Options`. Invalid options fa
- `ServiceName` cannot be null, empty, or whitespace.
- `ActivitySources` and `Meters` cannot contain null, empty, or whitespace names.
- OTLP `Endpoint`, when set, must be an absolute URI.
- OTLP `Protocol`, when set, must be `grpc` or `http/protobuf`.
- OTLP `Protocol`, when set, must be a defined `OtlpExportProtocol` value such as `Grpc` or `HttpProtobuf`.
- OTLP header names cannot be empty and cannot contain `,` or `=`.
- OTLP header values cannot be null and cannot contain `,`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OpenTelemetry.Exporter;

namespace OpenTelemetry.UnitTests.DependencyInjection;

Expand Down Expand Up @@ -195,7 +196,7 @@ public void AddAtyaOpenTelemetry_Should_Register_OpenTelemetryOptions()
options.Meters.Add("Orders.Business");
options.Exporters.Otlp.Enabled = true;
options.Exporters.Otlp.Endpoint = "http://localhost:4317";
options.Exporters.Otlp.Protocol = "grpc";
options.Exporters.Otlp.Protocol = OtlpExportProtocol.Grpc;
options.Exporters.Otlp.Headers["authorization"] = "Bearer token";
options.Instrumentations.AspNetCore.Enabled = true;
options.Instrumentations.HttpClient.Enabled = true;
Expand All @@ -218,7 +219,7 @@ public void AddAtyaOpenTelemetry_Should_Register_OpenTelemetryOptions()
_ = resolvedOptions.Meters.Should().ContainSingle("Orders.Business");
_ = resolvedOptions.Exporters.Otlp.Enabled.Should().BeTrue();
_ = resolvedOptions.Exporters.Otlp.Endpoint.Should().Be("http://localhost:4317");
_ = resolvedOptions.Exporters.Otlp.Protocol.Should().Be("grpc");
_ = resolvedOptions.Exporters.Otlp.Protocol.Should().Be(OtlpExportProtocol.Grpc);
_ = resolvedOptions.Exporters.Otlp.Headers.Should().ContainKey("authorization");
_ = resolvedOptions.Instrumentations.AspNetCore.Enabled.Should().BeTrue();
_ = resolvedOptions.Instrumentations.HttpClient.Enabled.Should().BeTrue();
Expand Down Expand Up @@ -249,7 +250,7 @@ public void AddAtyaOpenTelemetry_Should_Bind_Options_From_Default_Configuration_
["OpenTelemetry:Instrumentations:GrpcClient:Enabled"] = "true",
["OpenTelemetry:Exporters:Otlp:Enabled"] = "true",
["OpenTelemetry:Exporters:Otlp:Endpoint"] = "http://collector:4317",
["OpenTelemetry:Exporters:Otlp:Protocol"] = "http/protobuf",
["OpenTelemetry:Exporters:Otlp:Protocol"] = "HttpProtobuf",
["OpenTelemetry:Exporters:Otlp:Headers:tenant"] = "billing",
})
.Build();
Expand All @@ -273,7 +274,7 @@ public void AddAtyaOpenTelemetry_Should_Bind_Options_From_Default_Configuration_
_ = resolvedOptions.Instrumentations.GrpcClient.Enabled.Should().BeTrue();
_ = resolvedOptions.Exporters.Otlp.Enabled.Should().BeTrue();
_ = resolvedOptions.Exporters.Otlp.Endpoint.Should().Be("http://collector:4317");
_ = resolvedOptions.Exporters.Otlp.Protocol.Should().Be("http/protobuf");
_ = resolvedOptions.Exporters.Otlp.Protocol.Should().Be(OtlpExportProtocol.HttpProtobuf);
_ = resolvedOptions.Exporters.Otlp.Headers.Should().Contain("tenant", "billing");
}

Expand Down
Loading
Loading