diff --git a/benchmarks/Benchmarks/packages.lock.json b/benchmarks/Benchmarks/packages.lock.json index 0c67ba90ca1..df7a8ff861c 100644 --- a/benchmarks/Benchmarks/packages.lock.json +++ b/benchmarks/Benchmarks/packages.lock.json @@ -67,8 +67,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -1195,7 +1195,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } } diff --git a/benchmarks/Profiling/packages.lock.json b/benchmarks/Profiling/packages.lock.json index 4fbb49c50f4..de0de546e14 100644 --- a/benchmarks/Profiling/packages.lock.json +++ b/benchmarks/Profiling/packages.lock.json @@ -31,8 +31,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -131,7 +131,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } } diff --git a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/packages.lock.json b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/packages.lock.json index 880da78d98b..58a52540640 100644 --- a/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/packages.lock.json +++ b/src/Elastic.Clients.Elasticsearch.JsonNetSerializer/packages.lock.json @@ -37,8 +37,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -143,7 +143,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } }, @@ -183,8 +183,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -332,7 +332,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } }, @@ -381,8 +381,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -529,7 +529,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } }, @@ -569,8 +569,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -709,7 +709,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } }, @@ -749,8 +749,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -849,7 +849,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } }, @@ -889,8 +889,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -989,7 +989,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } } } diff --git a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs index 46358a9bd93..e271a12bdf8 100644 --- a/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs +++ b/src/Elastic.Clients.Elasticsearch/Api/SearchRequest.cs @@ -17,7 +17,7 @@ internal override void BeforeRequest() } } - protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) + protected override (string ResolvedUrl, string UrlTemplate) ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) { if (Pit is not null && !string.IsNullOrEmpty(Pit.Id ?? string.Empty) && routeValues.ContainsKey("index")) { @@ -60,7 +60,7 @@ internal override void BeforeRequest() } } - protected override string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) + protected override (string ResolvedUrl, string UrlTemplate) ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) { if ((Self.PitValue is not null || Self.PitDescriptor is not null || Self.PitDescriptorAction is not null) && routeValues.ContainsKey("index")) { diff --git a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs index 0085aca8e64..ad30b037a8b 100644 --- a/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs +++ b/src/Elastic.Clients.Elasticsearch/Client/ElasticsearchClient.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Text.Json; @@ -21,6 +22,8 @@ public partial class ElasticsearchClient { private readonly HttpTransport _transport; + private readonly ActivitySource _activitySource = new("Elastic.Clients.Elasticsearch.ElasticsearchClient"); + internal static ConditionalWeakTable SettingsTable { get; } = new(); /// @@ -127,8 +130,16 @@ internal TResponse DoRequest( } } - var (url, postData) = PrepareRequest(request, forceConfiguration); - var response = _transport.Request(request.HttpMethod, url, postData, parameters); + var (resolvedUrl, urlTemplate, postData) = PrepareRequest(request, forceConfiguration); + + TResponse response; + + using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client)) + { + activity?.AddTag("db.system", "elasticsearch"); + response = _transport.Request(request.HttpMethod, resolvedUrl, postData, parameters); + } + PostRequestProductCheck(request, response); if (_productCheckStatus == ProductCheckStatus.Failed) @@ -187,8 +198,21 @@ internal TResponse DoRequest( } } - var (url, postData) = PrepareRequest(request, forceConfiguration); - var response = _transport.Request(request.HttpMethod, url, postData, request.RequestParameters); + var (resolvedUrl, urlTemplate, postData) = PrepareRequest(request, forceConfiguration); + + TResponse response; + + using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client)) + { + activity?.AddTag("db.system", "elasticsearch"); + activity?.SetCustomProperty("elastic.transport.client", true); + + response = _transport.Request(request.HttpMethod, resolvedUrl, postData, request.RequestParameters); + + if (response.ApiCallDetails.RequestBodyInBytes is not null) + activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes)); + } + PostRequestProductCheck(request, response); if (_productCheckStatus == ProductCheckStatus.Failed) @@ -249,16 +273,28 @@ internal Task DoRequestAsync } } - var (url, postData) = PrepareRequest(request, null); + var (resolvedUrl, urlTemplate, postData) = PrepareRequest(request, null); - if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified) - return _transport.RequestAsync(request.HttpMethod, url, postData, parameters, cancellationToken); + if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners()) + return _transport.RequestAsync(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken); - return SendRequest(request, parameters, url, postData, hadRequestConfig, originalHeaders); + return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders); async Task SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders) { - var response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + TResponse response; + + using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client)) + { + activity?.AddTag("db.system", "elasticsearch"); + activity?.SetCustomProperty("elastic.transport.client", true); + + response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + + if (response.ApiCallDetails.RequestBodyInBytes is not null) + activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes)); + } + PostRequestProductCheck(request, response); if (_productCheckStatus == ProductCheckStatus.Failed) @@ -319,16 +355,28 @@ internal Task DoRequestAsync } } - var (url, postData) = PrepareRequest(request, null); + var (resolvedUrl, urlTemplate, postData) = PrepareRequest(request, null); - if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified) - return _transport.RequestAsync(request.HttpMethod, url, postData, request.RequestParameters, cancellationToken); + if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners()) + return _transport.RequestAsync(request.HttpMethod, resolvedUrl, postData, request.RequestParameters, cancellationToken); - return SendRequest(request, request.RequestParameters, url, postData, hadRequestConfig, originalHeaders); + return SendRequest(request, request.RequestParameters, resolvedUrl, postData, hadRequestConfig, originalHeaders); async Task SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders) { - var response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + TResponse response; + + using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client)) + { + activity?.AddTag("db.system", "elasticsearch"); + activity?.SetCustomProperty("elastic.transport.client", true); + + response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + + if (response.ApiCallDetails.RequestBodyInBytes is not null) + activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes)); + } + PostRequestProductCheck(request, response); if (_productCheckStatus == ProductCheckStatus.Failed) @@ -391,16 +439,28 @@ internal Task DoRequestAsync } } - var (url, postData) = PrepareRequest(request, forceConfiguration); + var (resolvedUrl, urlTemplate, postData) = PrepareRequest(request, null); - if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified) - return _transport.RequestAsync(request.HttpMethod, url, postData, parameters, cancellationToken); + if (_productCheckStatus == ProductCheckStatus.Succeeded && !requestModified && !_activitySource.HasListeners()) + return _transport.RequestAsync(request.HttpMethod, resolvedUrl, postData, parameters, cancellationToken); - return SendRequest(request, parameters, url, postData, hadRequestConfig, originalHeaders); + return SendRequest(request, parameters, resolvedUrl, postData, hadRequestConfig, originalHeaders); async Task SendRequest(TRequest request, RequestParameters? parameters, string url, PostData postData, bool hadRequestConfig, HeadersList? originalHeaders) { - var response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + TResponse response; + + using (var activity = _activitySource.StartActivity($"Elasticsearch: {request.HttpMethod} {urlTemplate}", ActivityKind.Client)) + { + activity?.AddTag("db.system", "elasticsearch"); + activity?.SetCustomProperty("elastic.transport.client", true); + + response = await _transport.RequestAsync(request.HttpMethod, url, postData, parameters).ConfigureAwait(false); + + if (response.ApiCallDetails.RequestBodyInBytes is not null) + activity?.AddTag("db.statement", System.Text.Encoding.UTF8.GetString(response.ApiCallDetails.RequestBodyInBytes)); + } + PostRequestProductCheck(request, response); if (_productCheckStatus == ProductCheckStatus.Failed) @@ -422,7 +482,7 @@ async Task SendRequest(TRequest request, RequestParameters? parameter } } - private (string url, PostData data) PrepareRequest(TRequest request, + private (string resolvedUrl, string urlTemplate, PostData data) PrepareRequest(TRequest request, Action? forceConfiguration) where TRequest : Request where TRequestParameters : RequestParameters, new() @@ -438,7 +498,7 @@ async Task SendRequest(TRequest request, RequestParameters? parameter if (request.Accept is not null) ForceAccept(request, request.Accept); - var url = request.GetUrl(ElasticsearchClientSettings); + var (resolvedUrl, urlTemplate) = request.GetUrl(ElasticsearchClientSettings); var postData = request.HttpMethod == HttpMethod.GET || @@ -446,7 +506,7 @@ async Task SendRequest(TRequest request, RequestParameters? parameter ? null : PostData.Serializable(request); - return (url, postData); + return (resolvedUrl, urlTemplate, postData); } private void PostRequestProductCheck(TRequest request, TResponse response) diff --git a/src/Elastic.Clients.Elasticsearch/Core/Request/ApiUrls.cs b/src/Elastic.Clients.Elasticsearch/Core/Request/ApiUrls.cs index 1df2582145e..05aeac1f51b 100644 --- a/src/Elastic.Clients.Elasticsearch/Core/Request/ApiUrls.cs +++ b/src/Elastic.Clients.Elasticsearch/Core/Request/ApiUrls.cs @@ -57,10 +57,10 @@ internal ApiUrls(string[] routes) /// public Dictionary> Routes { get; } - public string Resolve(RouteValues routeValues, IElasticsearchClientSettings settings) + public (string ResolvedUrl, string UrlTemplate) Resolve(RouteValues routeValues, IElasticsearchClientSettings settings) { if (_fixedUrl != null) - return _fixedUrl; + return (_fixedUrl, _fixedUrl); var resolved = routeValues.Resolve(settings); @@ -68,13 +68,13 @@ public string Resolve(RouteValues routeValues, IElasticsearchClientSettings sett throw new Exception($"No route taking {resolved.Count} parameters{_errorMessageSuffix}"); if (routes.Count == 1) - return routes[0].ToUrl(resolved); + return (routes[0].ToUrl(resolved), routes[0].Route); //find the first url with N parts that has all provided named parts foreach (var u in routes) { if (u.Matches(resolved)) - return u.ToUrl(resolved); + return (u.ToUrl(resolved), u.Route); } throw new Exception($"No route taking {routeValues.Count} parameters{_errorMessageSuffix}"); diff --git a/src/Elastic.Clients.Elasticsearch/Core/Request/Request.cs b/src/Elastic.Clients.Elasticsearch/Core/Request/Request.cs index c27868e1f60..14b85499348 100644 --- a/src/Elastic.Clients.Elasticsearch/Core/Request/Request.cs +++ b/src/Elastic.Clients.Elasticsearch/Core/Request/Request.cs @@ -26,12 +26,12 @@ internal Request() { } internal abstract ApiUrls ApiUrls { get; } - protected virtual string ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) => - ApiUrls.Resolve(routeValues, settings); + protected virtual (string ResolvedUrl, string UrlTemplate) ResolveUrl(RouteValues routeValues, IElasticsearchClientSettings settings) => + ApiUrls.Resolve(routeValues, settings); internal virtual void BeforeRequest() { } - internal string GetUrl(IElasticsearchClientSettings settings) => ResolveUrl(RouteValues, settings); + internal (string ResolvedUrl, string UrlTemplate) GetUrl(IElasticsearchClientSettings settings) => ResolveUrl(RouteValues, settings); } public abstract class Request : Request diff --git a/src/Elastic.Clients.Elasticsearch/Core/Request/UrlLookup.cs b/src/Elastic.Clients.Elasticsearch/Core/Request/UrlLookup.cs index aa026729436..55e2f8f4624 100644 --- a/src/Elastic.Clients.Elasticsearch/Core/Request/UrlLookup.cs +++ b/src/Elastic.Clients.Elasticsearch/Core/Request/UrlLookup.cs @@ -11,13 +11,13 @@ namespace Elastic.Clients.Elasticsearch.Requests; internal class UrlLookup { private readonly string[] _parts; - private readonly string _route; private readonly string[] _tokenized; private readonly int _length; public UrlLookup(string route) { - _route = route; + Route = route; + _tokenized = route.Replace("{", "{@") .Split(new[] { '{', '}' }, StringSplitOptions.RemoveEmptyEntries); @@ -26,9 +26,11 @@ public UrlLookup(string route) .Select(p => p.Remove(0, 1)) .ToArray(); - _length = _route.Length + (_parts.Length * 4); + _length = Route.Length + (_parts.Length * 4); } + public string Route { get; } + public bool Matches(ResolvedRouteValues values) { for (var i = 0; i < _parts.Length; i++) @@ -54,12 +56,12 @@ public string ToUrl(ResolvedRouteValues values) if (values.TryGetValue(_parts[i], out var v)) { if (string.IsNullOrEmpty(v)) - throw new Exception($"'{_parts[i]}' defined but is empty on url: {_route}"); + throw new Exception($"'{_parts[i]}' defined but is empty on url: {Route}"); sb.Append(Uri.EscapeDataString(v)); } else - throw new Exception($"No value provided for '{_parts[i]}' on url: {_route}"); + throw new Exception($"No value provided for '{_parts[i]}' on url: {Route}"); i++; } diff --git a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj index e2c7bb63457..d07716572bf 100644 --- a/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj +++ b/src/Elastic.Clients.Elasticsearch/Elastic.Clients.Elasticsearch.csproj @@ -17,7 +17,7 @@ annotations - + all runtime; build; native; contentfiles; analyzers diff --git a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs index ead1f141e40..fb6b97ee818 100644 --- a/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs +++ b/src/Elastic.Clients.Elasticsearch/Helpers/BulkAllObservable.cs @@ -118,9 +118,10 @@ private async Task BulkAsync(IList buffer, long page, int ba _compositeCancelToken.ThrowIfCancellationRequested(); var request = _partitionedBulkRequest; - + var response = await _client.BulkAsync(s => { + s.RequestParameters.RequestConfiguration = new RequestConfiguration { DisableAuditTrail = false }; s.Index(request.Index); s.Timeout(request.Timeout); diff --git a/src/Elastic.Clients.Elasticsearch/packages.lock.json b/src/Elastic.Clients.Elasticsearch/packages.lock.json index 4712eae0189..e48beb683ad 100644 --- a/src/Elastic.Clients.Elasticsearch/packages.lock.json +++ b/src/Elastic.Clients.Elasticsearch/packages.lock.json @@ -22,9 +22,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -163,9 +163,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -347,9 +347,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -539,9 +539,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -714,9 +714,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -849,9 +849,9 @@ }, "Elastic.Transport": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", diff --git a/src/Playground/packages.lock.json b/src/Playground/packages.lock.json index c56f0612e5e..9fd4362dd33 100644 --- a/src/Playground/packages.lock.json +++ b/src/Playground/packages.lock.json @@ -48,8 +48,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -153,7 +153,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": { diff --git a/tests/Tests.ClusterLauncher/packages.lock.json b/tests/Tests.ClusterLauncher/packages.lock.json index a35874d5be4..76512ddc2ed 100644 --- a/tests/Tests.ClusterLauncher/packages.lock.json +++ b/tests/Tests.ClusterLauncher/packages.lock.json @@ -75,8 +75,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -1271,7 +1271,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": { @@ -1388,8 +1388,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -2588,7 +2588,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": { @@ -2705,8 +2705,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -3905,7 +3905,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": { diff --git a/tests/Tests.Core/Client/TestClient.cs b/tests/Tests.Core/Client/TestClient.cs index 92b258f7670..782c531f7a4 100644 --- a/tests/Tests.Core/Client/TestClient.cs +++ b/tests/Tests.Core/Client/TestClient.cs @@ -14,15 +14,15 @@ public static class TestClient public static readonly TestConfigurationBase Configuration = TestConfiguration.Instance; public static readonly ElasticsearchClient Default = - new ElasticsearchClient(new TestElasticsearchClientSettings().ApplyDomainSettings()); + new(new TestElasticsearchClientSettings().ApplyDomainSettings()); public static readonly ElasticsearchClient DefaultInMemoryClient = - new ElasticsearchClient(new AlwaysInMemoryElasticsearchClientSettings().ApplyDomainSettings()); + new(new AlwaysInMemoryElasticsearchClientSettings().ApplyDomainSettings()); public static readonly ElasticsearchClient DisabledStreaming = - new ElasticsearchClient(new TestElasticsearchClientSettings().ApplyDomainSettings().DisableDirectStreaming()); + new(new TestElasticsearchClientSettings().ApplyDomainSettings().DisableDirectStreaming()); - public static ElasticsearchClient FixedInMemoryClient(byte[] response) => new ElasticsearchClient( + public static ElasticsearchClient FixedInMemoryClient(byte[] response) => new( new AlwaysInMemoryElasticsearchClientSettings(response) .ApplyDomainSettings() .DisableDirectStreaming() diff --git a/tests/Tests.Core/ManagedElasticsearch/Clusters/OpenTelemtryCluster.cs b/tests/Tests.Core/ManagedElasticsearch/Clusters/OpenTelemtryCluster.cs new file mode 100644 index 00000000000..7067cd327df --- /dev/null +++ b/tests/Tests.Core/ManagedElasticsearch/Clusters/OpenTelemtryCluster.cs @@ -0,0 +1,10 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +namespace Tests.Core.ManagedElasticsearch.Clusters; + +public class OpenTelemtryCluster : ClientTestClusterBase +{ + public OpenTelemtryCluster() : base() { } +} diff --git a/tests/Tests.Core/packages.lock.json b/tests/Tests.Core/packages.lock.json index ad79494e0aa..5a41abde4cf 100644 --- a/tests/Tests.Core/packages.lock.json +++ b/tests/Tests.Core/packages.lock.json @@ -137,8 +137,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -1589,7 +1589,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": { diff --git a/tests/Tests.Domain/packages.lock.json b/tests/Tests.Domain/packages.lock.json index 854d7f49fec..35b97de0107 100644 --- a/tests/Tests.Domain/packages.lock.json +++ b/tests/Tests.Domain/packages.lock.json @@ -57,8 +57,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -1142,7 +1142,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "tests.configuration": { diff --git a/tests/Tests/ClientConcepts/OpenTelemetry/ActivityTest.cs b/tests/Tests/ClientConcepts/OpenTelemetry/ActivityTest.cs new file mode 100644 index 00000000000..865e9e02836 --- /dev/null +++ b/tests/Tests/ClientConcepts/OpenTelemetry/ActivityTest.cs @@ -0,0 +1,57 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using System.Threading.Tasks; +using Tests.Core.Client; +using Tests.Domain; + +namespace Tests.ClientConcepts.OpenTelemetry; + +public class ActivityTest +{ + [U] + public async Task BasicOpenTelemetryTest() + { + Activity oTelActivity = null; + var listener = new ActivityListener + { + ActivityStarted = _ => { }, + ActivityStopped = activity => oTelActivity = activity, + ShouldListenTo = activitySource => activitySource.Name == "Elastic.Clients.Elasticsearch.ElasticsearchClient", + Sample = (ref ActivityCreationOptions _) => ActivitySamplingResult.AllData + }; + ActivitySource.AddActivityListener(listener); + + var client = TestClient.DefaultInMemoryClient; + + client.Ping(); + + VerifyActivity(oTelActivity); + + await client.PingAsync(); + + VerifyActivity(oTelActivity); + + await client.SearchAsync(s => s.Index("test").Query(q => q.MatchAll())); + + VerifyActivity(oTelActivity, "Elasticsearch: POST /{index}/_search", "http://localhost:9200/test/_search?pretty=true&error_trace=true"); + + static void VerifyActivity(Activity oTelActivity, string name = null, string url = null) + { + oTelActivity.Should().NotBeNull(); + + oTelActivity.Kind.Should().Be(ActivityKind.Client); + + oTelActivity.DisplayName.Should().Be(name ?? "Elasticsearch: HEAD /"); + oTelActivity.OperationName.Should().Be(name ?? "Elasticsearch: HEAD /"); + + oTelActivity.Tags.Should().Contain(n => n.Key == "db.system" && n.Value == "elasticsearch"); + oTelActivity.Tags.Should().Contain(n => n.Key == "http.url" && n.Value == (url ?? "http://localhost:9200/?pretty=true&error_trace=true")); + oTelActivity.Tags.Should().Contain(n => n.Key == "net.peer.name" && n.Value == "localhost"); + + oTelActivity.Status.Should().Be(ActivityStatusCode.Ok); + } + } +} diff --git a/tests/Tests/ClientConcepts/OpenTelemetry/OpenTelemetryActivityTest.cs b/tests/Tests/ClientConcepts/OpenTelemetry/OpenTelemetryActivityTest.cs new file mode 100644 index 00000000000..2976112480b --- /dev/null +++ b/tests/Tests/ClientConcepts/OpenTelemetry/OpenTelemetryActivityTest.cs @@ -0,0 +1,68 @@ +// Licensed to Elasticsearch B.V under one or more agreements. +// Elasticsearch B.V licenses this file to you under the Apache 2.0 License. +// See the LICENSE file in the project root for more information. + +using System.Diagnostics; +using Tests.Core.Client.Settings; +using Tests.Core.ManagedElasticsearch.Clusters; +using Tests.Framework.EndpointTests; +using Tests.Framework.EndpointTests.TestState; + +namespace Tests.ClientConcepts.OpenTelemetry; + +/// +/// Asserts that emits an OpenTelemetry compatible . +/// +public class OpenTelemetryActivityTest : ApiIntegrationTestBase +{ + Activity _oTelActivity = null; + ActivityListener _listener = null; + + public OpenTelemetryActivityTest(OpenTelemtryCluster cluster, EndpointUsage usage) : base(cluster, usage) { } + + protected override bool ExpectIsValid => true; + protected override int ExpectStatusCode => 200; + protected override HttpMethod HttpMethod => HttpMethod.HEAD; + protected override string ExpectedUrlPathAndQuery => "/"; + + protected override void IntegrationSetup(ElasticsearchClient client, CallUniqueValues values) + { + _listener = new ActivityListener + { + ActivityStarted = _ => { }, + ActivityStopped = activity => _oTelActivity = activity, + ShouldListenTo = activitySource => activitySource.Name == "Elastic.Clients.Elasticsearch.ElasticsearchClient", + Sample = (ref ActivityCreationOptions _) => ActivitySamplingResult.AllData + }; + + ActivitySource.AddActivityListener(_listener); + } + + protected override void IntegrationTeardown(ElasticsearchClient client, CallUniqueValues values) + { + _listener.Dispose(); + } + + protected override LazyResponses ClientUsage() => Calls( + (client, f) => client.Ping(), + (client, f) => client.PingAsync(), + (client, r) => client.Ping(r), + (client, r) => client.PingAsync(r) + ); + + protected override void OnAfterCall(ElasticsearchClient client) + { + _oTelActivity.Should().NotBeNull(); + + _oTelActivity.Kind.Should().Be(ActivityKind.Client); + + _oTelActivity.DisplayName.Should().Be("Elasticsearch: HEAD /"); + _oTelActivity.OperationName.Should().Be("Elasticsearch: HEAD /"); + + _oTelActivity.Tags.Should().Contain(n => n.Key == "db.system" && n.Value == "elasticsearch"); + _oTelActivity.Tags.Should().Contain(n => n.Key == "http.url" && n.Value == $"http://{TestElasticsearchClientSettings.LocalOrProxyHost}:9200/?pretty=true&error_trace=true"); + _oTelActivity.Tags.Should().Contain(n => n.Key == "net.peer.name" && n.Value == TestElasticsearchClientSettings.LocalOrProxyHost); + + _oTelActivity.Status.Should().Be(ActivityStatusCode.Ok); + } +} diff --git a/tests/Tests/Tests.csproj b/tests/Tests/Tests.csproj index aa817fdf9c8..6dc95877b0a 100644 --- a/tests/Tests/Tests.csproj +++ b/tests/Tests/Tests.csproj @@ -10,7 +10,7 @@ - + diff --git a/tests/Tests/packages.lock.json b/tests/Tests/packages.lock.json index 94d233ae460..a2f90ff7457 100644 --- a/tests/Tests/packages.lock.json +++ b/tests/Tests/packages.lock.json @@ -31,11 +31,11 @@ }, "Elastic.Transport.VirtualizedCluster": { "type": "Direct", - "requested": "[0.4.2, )", - "resolved": "0.4.2", - "contentHash": "tyPrSQqfEPQjHVWDpZ+NbnuI4i6S5DXPQeJvgoqpHdD8l8g+3Luv3/0bRIms6L1neSzXZ+riPtHS9muGNV/1pQ==", + "requested": "[0.4.3, )", + "resolved": "0.4.3", + "contentHash": "U4Ss5iT3uuhzSo8es0TWh2HIeRENEyIq+0VsedJR7fjq3dbiErIqBR5bU3mA8D4b2Agac2sKNThVuGfdZHcxtg==", "dependencies": { - "Elastic.Transport": "0.4.2" + "Elastic.Transport": "0.4.3" } }, "FSharp.Core": { @@ -195,8 +195,8 @@ }, "Elastic.Transport": { "type": "Transitive", - "resolved": "0.4.2", - "contentHash": "umDR9uAzO8KPgb96O6llqN7DIv7oqATB4MPr3UrDCJ6Su+l7KJhB7lwItf/cw727e1jKTG9QEqkW6tBGjYoe4w==", + "resolved": "0.4.3", + "contentHash": "U4yHxScZG7YMDJJ9KGGWfhNx543NQmWlNPILyrd5UF0VMFfjuTZ+RXtWRCX8xMrqcSl4pUBKE+G4GoIVA65ZUQ==", "dependencies": { "Microsoft.CSharp": "4.7.0", "System.Buffers": "4.5.1", @@ -1492,7 +1492,7 @@ "elastic.clients.elasticsearch": { "type": "Project", "dependencies": { - "Elastic.Transport": "[0.4.2, )" + "Elastic.Transport": "[0.4.3, )" } }, "elastic.clients.elasticsearch.jsonnetserializer": {