Skip to content

Commit ec94b60

Browse files
Respond to Transport changes and support OpenTelemetry (#6990) (#6991)
* Respond to Transport changes and support OpenTelemetry * Fix BOM Co-authored-by: Steve Gordon <[email protected]>
1 parent df991b4 commit ec94b60

File tree

21 files changed

+308
-110
lines changed

21 files changed

+308
-110
lines changed

benchmarks/Benchmarks/packages.lock.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@
6767
},
6868
"Elastic.Transport": {
6969
"type": "Transitive",
70-
"resolved": "0.4.2",
71-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
70+
"resolved": "0.4.3",
71+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
7272
"dependencies": {
7373
"Microsoft.CSharp": "4.7.0",
7474
"System.Buffers": "4.5.1",
@@ -1195,7 +1195,7 @@
11951195
"elastic.clients.elasticsearch": {
11961196
"type": "Project",
11971197
"dependencies": {
1198-
"Elastic.Transport": "[0.4.2, )"
1198+
"Elastic.Transport": "[0.4.3, )"
11991199
}
12001200
}
12011201
}

benchmarks/Profiling/packages.lock.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@
3131
},
3232
"Elastic.Transport": {
3333
"type": "Transitive",
34-
"resolved": "0.4.2",
35-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
34+
"resolved": "0.4.3",
35+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
3636
"dependencies": {
3737
"Microsoft.CSharp": "4.7.0",
3838
"System.Buffers": "4.5.1",
@@ -131,7 +131,7 @@
131131
"elastic.clients.elasticsearch": {
132132
"type": "Project",
133133
"dependencies": {
134-
"Elastic.Transport": "[0.4.2, )"
134+
"Elastic.Transport": "[0.4.3, )"
135135
}
136136
}
137137
}

src/Elastic.Clients.Elasticsearch.JsonNetSerializer/packages.lock.json

+18-18
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
},
3838
"Elastic.Transport": {
3939
"type": "Transitive",
40-
"resolved": "0.4.2",
41-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
40+
"resolved": "0.4.3",
41+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
4242
"dependencies": {
4343
"Microsoft.CSharp": "4.7.0",
4444
"System.Buffers": "4.5.1",
@@ -143,7 +143,7 @@
143143
"elastic.clients.elasticsearch": {
144144
"type": "Project",
145145
"dependencies": {
146-
"Elastic.Transport": "[0.4.2, )"
146+
"Elastic.Transport": "[0.4.3, )"
147147
}
148148
}
149149
},
@@ -183,8 +183,8 @@
183183
},
184184
"Elastic.Transport": {
185185
"type": "Transitive",
186-
"resolved": "0.4.2",
187-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
186+
"resolved": "0.4.3",
187+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
188188
"dependencies": {
189189
"Microsoft.CSharp": "4.7.0",
190190
"System.Buffers": "4.5.1",
@@ -332,7 +332,7 @@
332332
"elastic.clients.elasticsearch": {
333333
"type": "Project",
334334
"dependencies": {
335-
"Elastic.Transport": "[0.4.2, )"
335+
"Elastic.Transport": "[0.4.3, )"
336336
}
337337
}
338338
},
@@ -381,8 +381,8 @@
381381
},
382382
"Elastic.Transport": {
383383
"type": "Transitive",
384-
"resolved": "0.4.2",
385-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
384+
"resolved": "0.4.3",
385+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
386386
"dependencies": {
387387
"Microsoft.CSharp": "4.7.0",
388388
"System.Buffers": "4.5.1",
@@ -529,7 +529,7 @@
529529
"elastic.clients.elasticsearch": {
530530
"type": "Project",
531531
"dependencies": {
532-
"Elastic.Transport": "[0.4.2, )"
532+
"Elastic.Transport": "[0.4.3, )"
533533
}
534534
}
535535
},
@@ -569,8 +569,8 @@
569569
},
570570
"Elastic.Transport": {
571571
"type": "Transitive",
572-
"resolved": "0.4.2",
573-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
572+
"resolved": "0.4.3",
573+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
574574
"dependencies": {
575575
"Microsoft.CSharp": "4.7.0",
576576
"System.Buffers": "4.5.1",
@@ -709,7 +709,7 @@
709709
"elastic.clients.elasticsearch": {
710710
"type": "Project",
711711
"dependencies": {
712-
"Elastic.Transport": "[0.4.2, )"
712+
"Elastic.Transport": "[0.4.3, )"
713713
}
714714
}
715715
},
@@ -749,8 +749,8 @@
749749
},
750750
"Elastic.Transport": {
751751
"type": "Transitive",
752-
"resolved": "0.4.2",
753-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
752+
"resolved": "0.4.3",
753+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
754754
"dependencies": {
755755
"Microsoft.CSharp": "4.7.0",
756756
"System.Buffers": "4.5.1",
@@ -849,7 +849,7 @@
849849
"elastic.clients.elasticsearch": {
850850
"type": "Project",
851851
"dependencies": {
852-
"Elastic.Transport": "[0.4.2, )"
852+
"Elastic.Transport": "[0.4.3, )"
853853
}
854854
}
855855
},
@@ -889,8 +889,8 @@
889889
},
890890
"Elastic.Transport": {
891891
"type": "Transitive",
892-
"resolved": "0.4.2",
893-
"contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==",
892+
"resolved": "0.4.3",
893+
"contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==",
894894
"dependencies": {
895895
"Microsoft.CSharp": "4.7.0",
896896
"System.Buffers": "4.5.1",
@@ -989,7 +989,7 @@
989989
"elastic.clients.elasticsearch": {
990990
"type": "Project",
991991
"dependencies": {
992-
"Elastic.Transport": "[0.4.2, )"
992+
"Elastic.Transport": "[0.4.3, )"
993993
}
994994
}
995995
}

src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ internal override void BeforeRequest()
1717
}
1818
}
1919

20-
protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings)
20+
protected override (string ResolvedUrl, string UrlTemplate) ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings)
2121
{
2222
if (Pit is not null && !string.IsNullOrEmpty(Pit.Id ?? string.Empty) && routeValues.ContainsKey("index"))
2323
{
@@ -60,7 +60,7 @@ internal override void BeforeRequest()
6060
}
6161
}
6262

63-
protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings)
63+
protected override (string ResolvedUrl, string UrlTemplate) ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings)
6464
{
6565
if ((Self.PitValue is not null || Self.PitDescriptor is not null || Self.PitDescriptorAction is not null) && routeValues.ContainsKey("index"))
6666
{

src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs

+82-22
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Diagnostics;
67
using System.Linq;
78
using System.Runtime.CompilerServices;
89
using System.Text.Json;
@@ -21,6 +22,8 @@ public partial class ElasticsearchClient
2122
{
2223
private readonly HttpTransport<IElasticsearchClientSettings> _transport;
2324

25+
private readonly ActivitySource _activitySource = new("Elastic.Clients.Elasticsearch.ElasticsearchClient");
26+
2427
internal static ConditionalWeakTable<JsonSerializerOptions, IElasticsearchClientSettings> SettingsTable { get; } = new();
2528

2629
/// <summary>
@@ -127,8 +130,16 @@ internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
127130
}
128131
}
129132

130-
var (url, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
131-
var response = _transport.Request<TResponse>(request.HttpMethod, url, postData, parameters);
133+
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
134+
135+
TResponse response;
136+
137+
using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
138+
{
139+
activity?.AddTag("db.system", "elasticsearch");
140+
response = _transport.Request<TResponse>(request.HttpMethod, resolvedUrl, postData, parameters);
141+
}
142+
132143
PostRequestProductCheck<TRequest, TResponse>(request, response);
133144

134145
if (_productCheckStatus == ProductCheckStatus.Failed)
@@ -187,8 +198,21 @@ internal TResponse DoRequest<TRequest, TResponse, TRequestParameters>(
187198
}
188199
}
189200

190-
var (url, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
191-
var response = _transport.Request<TResponse>(request.HttpMethod, url, postData, request.RequestParameters);
201+
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
202+
203+
TResponse response;
204+
205+
using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
206+
{
207+
activity?.AddTag("db.system", "elasticsearch");
208+
activity?.SetCustomProperty("elastic.transport.client", true);
209+
210+
response = _transport.Request<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters);
211+
212+
if (response.ApiCallDetails.RequestBodyInBytes is not null)
213+
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
214+
}
215+
192216
PostRequestProductCheck<TRequest, TResponse>(request, response);
193217

194218
if (_productCheckStatus == ProductCheckStatus.Failed)
@@ -249,16 +273,28 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
249273
}
250274
}
251275

252-
var (url, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);
276+
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);
253277

254-
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified)
255-
return _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters, cancellationToken);
278+
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
279+
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken);
256280

257-
return SendRequest(request, parameters, url, postData, hadRequestConfig, originalHeaders);
281+
return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);
258282

259283
async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
260284
{
261-
var response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
285+
TResponse response;
286+
287+
using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
288+
{
289+
activity?.AddTag("db.system", "elasticsearch");
290+
activity?.SetCustomProperty("elastic.transport.client", true);
291+
292+
response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
293+
294+
if (response.ApiCallDetails.RequestBodyInBytes is not null)
295+
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
296+
}
297+
262298
PostRequestProductCheck<TRequest, TResponse>(request, response);
263299

264300
if (_productCheckStatus == ProductCheckStatus.Failed)
@@ -319,16 +355,28 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
319355
}
320356
}
321357

322-
var (url, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);
358+
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);
323359

324-
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified)
325-
return _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, request.RequestParameters, cancellationToken);
360+
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
361+
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, cancellationToken);
326362

327-
return SendRequest(request, request.RequestParameters, url, postData, hadRequestConfig, originalHeaders);
363+
return SendRequest(request, request.RequestParameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);
328364

329365
async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
330366
{
331-
var response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
367+
TResponse response;
368+
369+
using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
370+
{
371+
activity?.AddTag("db.system", "elasticsearch");
372+
activity?.SetCustomProperty("elastic.transport.client", true);
373+
374+
response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
375+
376+
if (response.ApiCallDetails.RequestBodyInBytes is not null)
377+
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
378+
}
379+
332380
PostRequestProductCheck<TRequest, TResponse>(request, response);
333381

334382
if (_productCheckStatus == ProductCheckStatus.Failed)
@@ -391,16 +439,28 @@ internal Task<TResponse> DoRequestAsync<TRequest, TResponse, TRequestParameters>
391439
}
392440
}
393441

394-
var (url, postData) = PrepareRequest<TRequest, TRequestParameters>(request, forceConfiguration);
442+
var (resolvedUrl, urlTemplate, postData) = PrepareRequest<TRequest, TRequestParameters>(request, null);
395443

396-
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified)
397-
return _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters, cancellationToken);
444+
if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners())
445+
return _transport.RequestAsync<TResponse>(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken);
398446

399-
return SendRequest(request, parameters, url, postData, hadRequestConfig, originalHeaders);
447+
return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders);
400448

401449
async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders)
402450
{
403-
var response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
451+
TResponse response;
452+
453+
using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client))
454+
{
455+
activity?.AddTag("db.system", "elasticsearch");
456+
activity?.SetCustomProperty("elastic.transport.client", true);
457+
458+
response = await _transport.RequestAsync<TResponse>(request.HttpMethod, url, postData, parameters).ConfigureAwait(false);
459+
460+
if (response.ApiCallDetails.RequestBodyInBytes is not null)
461+
activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes));
462+
}
463+
404464
PostRequestProductCheck<TRequest, TResponse>(request, response);
405465

406466
if (_productCheckStatus == ProductCheckStatus.Failed)
@@ -422,7 +482,7 @@ async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameter
422482
}
423483
}
424484

425-
private (string url, PostData data) PrepareRequest<TRequest, TRequestParameters>(TRequest request,
485+
private (string resolvedUrl, string urlTemplate, PostData data) PrepareRequest<TRequest, TRequestParameters>(TRequest request,
426486
Action<IRequestConfiguration>? forceConfiguration)
427487
where TRequest : Request<TRequestParameters>
428488
where TRequestParameters : RequestParameters, new()
@@ -438,15 +498,15 @@ async Task<TResponse> SendRequest(TRequest request, RequestParameters? parameter
438498
if (request.Accept is not null)
439499
ForceAccept<TRequest, TRequestParameters>(request, request.Accept);
440500

441-
var url = request.GetUrl(ElasticsearchClientSettings);
501+
var (resolvedUrl, urlTemplate) = request.GetUrl(ElasticsearchClientSettings);
442502

443503
var postData =
444504
request.HttpMethod == HttpMethod.GET ||
445505
request.HttpMethod == HttpMethod.HEAD || !request.SupportsBody
446506
? null
447507
: PostData.Serializable(request);
448508

449-
return (url, postData);
509+
return (resolvedUrl, urlTemplate, postData);
450510
}
451511

452512
private void PostRequestProductCheck<TRequest, TResponse>(TRequest request, TResponse response)

src/Elastic.Clients.Elasticsearch/Core/Request/ApiUrls.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,24 @@ internal ApiUrls(string[] routes)
5757
/// </summary>
5858
public Dictionary<int, List<UrlLookup>> Routes { get; }
5959

60-
public string Resolve(RouteValues routeValues, IElasticsearchClientSettings settings)
60+
public (string ResolvedUrl, string UrlTemplate) Resolve(RouteValues routeValues, IElasticsearchClientSettings settings)
6161
{
6262
if (_fixedUrl != null)
63-
return _fixedUrl;
63+
return (_fixedUrl, _fixedUrl);
6464

6565
var resolved = routeValues.Resolve(settings);
6666

6767
if (!Routes.TryGetValue(resolved.Count, out var routes))
6868
throw new Exception($"No route taking {resolved.Count} parameters{_errorMessageSuffix}");
6969

7070
if (routes.Count == 1)
71-
return routes[0].ToUrl(resolved);
71+
return (routes[0].ToUrl(resolved), routes[0].Route);
7272

7373
//find the first url with N parts that has all provided named parts
7474
foreach (var u in routes)
7575
{
7676
if (u.Matches(resolved))
77-
return u.ToUrl(resolved);
77+
return (u.ToUrl(resolved), u.Route);
7878
}
7979

8080
throw new Exception($"No route taking {routeValues.Count} parameters{_errorMessageSuffix}");

0 commit comments

Comments
 (0)