private async Task <bool> SendTracesAsync(ArraySegment <byte> traces, int numberOfTraces, IApiRequest request, bool finalTry) { IApiResponse response = null; try { try { _statsd?.Increment(TracerMetricNames.Api.Requests); response = await request.PostAsync(traces, MimeTypes.MsgPack).ConfigureAwait(false); } catch { // count only network/infrastructure errors, not valid responses with error status codes // (which are handled below) _statsd?.Increment(TracerMetricNames.Api.Errors); throw; } if (_statsd != null) { // don't bother creating the tags array if trace metrics are disabled string[] tags = { $"status:{response.StatusCode}" }; // count every response, grouped by status code _statsd?.Increment(TracerMetricNames.Api.Responses, tags: tags); } // Attempt a retry if the status code is not SUCCESS if (response.StatusCode < 200 || response.StatusCode >= 300) { if (finalTry) { try { string responseContent = await response.ReadAsStringAsync().ConfigureAwait(false); _log.Error <int, string>("Failed to submit traces with status code {StatusCode} and message: {ResponseContent}", response.StatusCode, responseContent); } catch (Exception ex) { _log.Error <int>(ex, "Unable to read response for failed request with status code {StatusCode}", response.StatusCode); } } return(false); } try { if (_agentVersion == null) { var version = response.GetHeader(AgentHttpHeaderNames.AgentVersion); LogPartialFlushWarningIfRequired(version ?? string.Empty); } if (response.ContentLength != 0 && _updateSampleRates is not null) { var responseContent = await response.ReadAsStringAsync().ConfigureAwait(false); if (responseContent != _cachedResponse) { var apiResponse = JsonConvert.DeserializeObject <ApiResponse>(responseContent); _updateSampleRates(apiResponse.RateByService); _cachedResponse = responseContent; } } } catch (Exception ex) { _log.Error(ex, "Traces sent successfully to the Agent at {AgentEndpoint}, but an error occurred deserializing the response.", _apiRequestFactory.Info(_tracesEndpoint)); } } finally { response?.Dispose(); } return(true); }