diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs b/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs
index 1427878606..cfe03c5161 100644
--- a/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs
+++ b/src/Elastic.Clients.Elasticsearch.Serverless/Core/ElasticsearchClientProductRegistration.cs
@@ -77,7 +77,7 @@ public class ApiVersionMetaHeaderProducer : MetaHeaderProducer
public override string HeaderName => "Elastic-Api-Version";
- public override string ProduceHeaderValue(RequestData requestData, bool isAsync) => _apiVersion;
+ public override string ProduceHeaderValue(BoundConfiguration boundConfiguration, bool isAsync) => _apiVersion;
public ApiVersionMetaHeaderProducer(VersionInfo version)
{
diff --git a/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj b/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj
index b35a3290ea..3f46babf24 100644
--- a/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj
+++ b/src/Elastic.Clients.Elasticsearch.Serverless/Elastic.Clients.Elasticsearch.Serverless.csproj
@@ -21,7 +21,7 @@
annotations
-
+
diff --git a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj
index 71cdf552e8..c4e6648318 100644
--- a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj
+++ b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj
@@ -21,7 +21,7 @@
annotations
-
+
diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs
index f4b002621f..981a599fcc 100644
--- a/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs
+++ b/src/Elastic.Clients.Elasticsearch/_Shared/Api/Esql/EsqlQueryRequest.cs
@@ -17,7 +17,7 @@ namespace Elastic.Clients.Elasticsearch.Esql;
internal sealed class EsqlResponseBuilder : TypedResponseBuilder
{
- protected override EsqlQueryResponse? Build(ApiCallDetails apiCallDetails, RequestData requestData,
+ protected override EsqlQueryResponse? Build(ApiCallDetails apiCallDetails, BoundConfiguration boundConfiguration,
Stream responseStream,
string contentType, long contentLength)
{
@@ -38,7 +38,7 @@ static byte[] BytesFromStream(Stream stream)
}
}
- protected override async Task BuildAsync(ApiCallDetails apiCallDetails, RequestData requestData,
+ protected override async Task BuildAsync(ApiCallDetails apiCallDetails, BoundConfiguration boundConfiguration,
Stream responseStream,
string contentType, long contentLength, CancellationToken cancellationToken = default)
{
diff --git a/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs b/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs
index 1e61176db5..faee0c33fb 100644
--- a/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs
+++ b/src/Elastic.Clients.Elasticsearch/_Shared/Client/ElasticsearchClient.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
@@ -165,11 +166,11 @@ private ValueTask DoRequestCoreAsync SendRequest()
{
var (endpointPath, resolvedRouteValues, postData) = PrepareRequest(request);
- var openTelemetryData = PrepareOpenTelemetryData(request, resolvedRouteValues);
+ var openTelemetryDataMutator = GetOpenTelemetryDataMutator(request, resolvedRouteValues);
return isAsync
- ? new ValueTask(_transport.RequestAsync(endpointPath, postData, in openTelemetryData, request.RequestConfig, cancellationToken))
- : new ValueTask(_transport.Request(endpointPath, postData, in openTelemetryData, request.RequestConfig));
+ ? new ValueTask(_transport.RequestAsync(endpointPath, postData, openTelemetryDataMutator, request.RequestConfig, cancellationToken))
+ : new ValueTask(_transport.Request(endpointPath, postData, openTelemetryDataMutator, request.RequestConfig));
}
async ValueTask SendRequestWithProductCheck()
@@ -211,19 +212,19 @@ async ValueTask SendRequestWithProductCheckCore()
// Send request
var (endpointPath, resolvedRouteValues, postData) = PrepareRequest(request);
- var openTelemetryData = PrepareOpenTelemetryData(request, resolvedRouteValues);
+ var openTelemetryDataMutator = GetOpenTelemetryDataMutator(request, resolvedRouteValues);
TResponse response;
if (isAsync)
{
response = await _transport
- .RequestAsync(endpointPath, postData, in openTelemetryData, requestConfig, cancellationToken)
+ .RequestAsync(endpointPath, postData, openTelemetryDataMutator, requestConfig, cancellationToken)
.ConfigureAwait(false);
}
else
{
- response = _transport.Request(endpointPath, postData, in openTelemetryData, requestConfig);
+ response = _transport.Request(endpointPath, postData, openTelemetryDataMutator, requestConfig);
}
// Evaluate product check result
@@ -252,39 +253,41 @@ async ValueTask SendRequestWithProductCheckCore()
}
}
- private static OpenTelemetryData PrepareOpenTelemetryData(TRequest request, Dictionary resolvedRouteValues)
+ private static Action? GetOpenTelemetryDataMutator(TRequest request, Dictionary? resolvedRouteValues)
where TRequest : Request
where TRequestParameters : RequestParameters, new()
{
// If there are no subscribed listeners, we avoid some work and allocations
if (!Elastic.Transport.Diagnostics.OpenTelemetry.ElasticTransportActivitySourceHasListeners)
- return default;
+ return null;
- // We fall back to a general operation name in cases where the derived request fails to override the property
- var operationName = !string.IsNullOrEmpty(request.OperationName) ? request.OperationName : request.HttpMethod.GetStringValue();
+ return OpenTelemetryDataMutator;
- // TODO: Optimisation: We should consider caching these, either for cases where resolvedRouteValues is null, or
- // caching per combination of route values.
- // We should benchmark this first to assess the impact for common workloads.
- // The former is likely going to save some short-lived allocations, but only for requests to endpoints without required path parts.
- // The latter may bloat the cache as some combinations of path parts may rarely re-occur.
- var attributes = new Dictionary
+ void OpenTelemetryDataMutator(Activity activity)
{
- [OpenTelemetry.SemanticConventions.DbOperation] = !string.IsNullOrEmpty(request.OperationName) ? request.OperationName : "unknown",
- [$"{OpenTelemetrySpanAttributePrefix}schema_url"] = OpenTelemetrySchemaVersion
- };
+ // We fall back to a general operation name in cases where the derived request fails to override the property
+ var operationName = !string.IsNullOrEmpty(request.OperationName) ? request.OperationName : request.HttpMethod.GetStringValue();
+
+ // TODO: Optimisation: We should consider caching these, either for cases where resolvedRouteValues is null, or
+ // caching per combination of route values.
+ // We should benchmark this first to assess the impact for common workloads.
+ // The former is likely going to save some short-lived allocations, but only for requests to endpoints without required path parts.
+ // The latter may bloat the cache as some combinations of path parts may rarely re-occur.
+
+ activity.DisplayName = operationName;
+
+ activity.SetTag(OpenTelemetry.SemanticConventions.DbOperation, !string.IsNullOrEmpty(request.OperationName) ? request.OperationName : "unknown");
+ activity.SetTag($"{OpenTelemetrySpanAttributePrefix}schema_url", OpenTelemetrySchemaVersion);
+
+ if (resolvedRouteValues is null)
+ return;
- if (resolvedRouteValues is not null)
- {
foreach (var value in resolvedRouteValues)
{
if (!string.IsNullOrEmpty(value.Key) && !string.IsNullOrEmpty(value.Value))
- attributes.Add($"{OpenTelemetrySpanAttributePrefix}path_parts.{value.Key}", value.Value);
+ activity.SetTag($"{OpenTelemetrySpanAttributePrefix}path_parts.{value.Key}", value.Value);
}
}
-
- var openTelemetryData = new OpenTelemetryData { SpanName = operationName, SpanAttributes = attributes };
- return openTelemetryData;
}
private (EndpointPath endpointPath, Dictionary? resolvedRouteValues, PostData data) PrepareRequest(TRequest request)
diff --git a/src/Playground/Playground.csproj b/src/Playground/Playground.csproj
index 455e7a6ebd..d26d64adac 100644
--- a/src/Playground/Playground.csproj
+++ b/src/Playground/Playground.csproj
@@ -10,7 +10,7 @@
-
+