From baa183c6365fa7640fd634f2ed3355ff8b39070f Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 18 Dec 2024 09:14:34 -0500 Subject: [PATCH 1/2] fix: aligns retry attribute names with latest OTEL spec Signed-off-by: Vincent Biret --- src/http/httpClient/HttpClientRequestAdapter.cs | 4 +++- src/http/httpClient/Middleware/RetryHandler.cs | 13 +++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/http/httpClient/HttpClientRequestAdapter.cs b/src/http/httpClient/HttpClientRequestAdapter.cs index 3e6f5de..5cf88a6 100644 --- a/src/http/httpClient/HttpClientRequestAdapter.cs +++ b/src/http/httpClient/HttpClientRequestAdapter.cs @@ -541,6 +541,8 @@ private async Task GetHttpResponseMessageAsync(RequestInfor /// public const string AuthenticateChallengedEventKey = "com.microsoft.kiota.authenticate_challenge_received"; + internal const string RetryCountAttributeName = "http.request.resend_count"; + private async Task RetryCAEResponseIfRequiredAsync(HttpResponseMessage response, RequestInformation requestInfo, CancellationToken cancellationToken, string? claims, Activity? activityForAttributes) { using var span = activitySource?.StartActivity(nameof(RetryCAEResponseIfRequiredAsync)); @@ -554,7 +556,7 @@ private async Task RetryCAEResponseIfRequiredAsync(HttpResp return response; } span?.AddEvent(new ActivityEvent(AuthenticateChallengedEventKey)); - activityForAttributes?.SetTag("http.retry_count", 1); + activityForAttributes?.SetTag(RetryCountAttributeName, 1); requestInfo.Content?.Seek(0, SeekOrigin.Begin); await DrainAsync(response, cancellationToken).ConfigureAwait(false); return await GetHttpResponseMessageAsync(requestInfo, cancellationToken, activityForAttributes, responseClaims).ConfigureAwait(false); diff --git a/src/http/httpClient/Middleware/RetryHandler.cs b/src/http/httpClient/Middleware/RetryHandler.cs index 4bed641..97fb414 100644 --- a/src/http/httpClient/Middleware/RetryHandler.cs +++ b/src/http/httpClient/Middleware/RetryHandler.cs @@ -105,11 +105,12 @@ private async Task SendRetryAsync(HttpResponseMessage respo { exceptions.Add(await GetInnerExceptionAsync(response).ConfigureAwait(false)); using var retryActivity = activitySource?.StartActivity($"{nameof(RetryHandler)}_{nameof(SendAsync)} - attempt {retryCount}"); - retryActivity?.SetTag("http.retry_count", retryCount); + retryActivity?.SetTag(HttpClientRequestAdapter.RetryCountAttributeName, retryCount); retryActivity?.SetTag("http.response.status_code", response.StatusCode); // Call Delay method to get delay time from response's Retry-After header or by exponential backoff - Task delay = RetryHandler.DelayAsync(response, retryCount, retryOption.Delay, out double delayInSeconds, cancellationToken); + var delay = DelayAsync(response, retryCount, retryOption.Delay, out double delayInSeconds, cancellationToken); + retryActivity?.SetTag("http.request.resend_delay", delayInSeconds); // If client specified a retries time limit, let's honor it if(retryOption.RetriesTimeLimit > TimeSpan.Zero) @@ -176,12 +177,12 @@ private static void AddOrUpdateRetryAttempt(HttpRequestMessage request, int retr /// /// The cancellationToken for the Http request /// The for delay operation. - internal static Task DelayAsync(HttpResponseMessage response, int retryCount, int delay, out double delayInSeconds, CancellationToken cancellationToken) + static internal Task DelayAsync(HttpResponseMessage response, int retryCount, int delay, out double delayInSeconds, CancellationToken cancellationToken) { delayInSeconds = delay; - if(response.Headers.TryGetValues(RetryAfter, out IEnumerable? values)) + if(response.Headers.TryGetValues(RetryAfter, out var values)) { - using IEnumerator v = values.GetEnumerator(); + using var v = values.GetEnumerator(); string retryAfter = v.MoveNext() ? v.Current : throw new InvalidOperationException("Retry-After header is empty."); // the delay could be in the form of a seconds or a http date. See https://httpwg.org/specs/rfc7231.html#header.retry-after if(int.TryParse(retryAfter, out int delaySeconds)) @@ -200,7 +201,7 @@ internal static Task DelayAsync(HttpResponseMessage response, int retryCount, in delayInSeconds = CalculateExponentialDelay(retryCount, delay); } - TimeSpan delayTimeSpan = TimeSpan.FromSeconds(Math.Min(delayInSeconds, RetryHandlerOption.MaxDelay)); + var delayTimeSpan = TimeSpan.FromSeconds(Math.Min(delayInSeconds, RetryHandlerOption.MaxDelay)); delayInSeconds = delayTimeSpan.TotalSeconds; return Task.Delay(delayTimeSpan, cancellationToken); } From b0828792f19e907d430f191cc671c54b892f7f23 Mon Sep 17 00:00:00 2001 From: Vincent Biret Date: Wed, 18 Dec 2024 09:16:25 -0500 Subject: [PATCH 2/2] chore: bumps patch version Signed-off-by: Vincent Biret --- CHANGELOG.md | 6 ++++++ Directory.Build.props | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 495ff05..7bf80e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.16.1] - 2024-12-18 + +### Changed + +- Aligned retry open telemetry attributes names with latest specification. [#324](https://github.com/microsoft/kiota-dotnet/issues/324) + ## [1.16.0] - 2024-12-13 ### Added diff --git a/Directory.Build.props b/Directory.Build.props index dd8db0b..f40df4e 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,7 +1,7 @@ - 1.16.0 + 1.16.1 false