public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { using (var bidirectionalStream = _streamFactory.GetBidirectionalStream()) { // buffer the entire contents for now so we can determine its size in bytes and avoid chunking. // TODO: support chunked transfer encoding to avoid buffering the entire contents var requestContentStream = new MemoryStream(); await CachedSerializer.Instance.SerializeAsync(requestContentStream, traces, formatterResolver).ConfigureAwait(false); requestContentStream.Position = 0; var content = new StreamContent(requestContentStream, requestContentStream.Length); var request = new HttpRequest("POST", _uri.Host, _uri.PathAndQuery, _headers, content); // send request, get response var response = await _client.SendAsync(request, bidirectionalStream, bidirectionalStream).ConfigureAwait(false); // buffer the entire contents for now var responseContentStream = new MemoryStream(); await response.Content.CopyToAsync(responseContentStream, DatadogHttpValues.MaximumResponseBufferSize).ConfigureAwait(false); responseContentStream.Position = 0; var contentLength = response.ContentLength; if (contentLength != null && contentLength != responseContentStream.Length) { throw new Exception("Content length from http headers does not match content's actual length."); } return(new HttpStreamResponse(response.StatusCode, responseContentStream.Length, response.GetContentEncoding(), responseContentStream)); } }
public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { using (var requestStream = Stream.Null) { await CachedSerializer.Instance.SerializeAsync(requestStream, traces, formatterResolver).ConfigureAwait(false); } return(new FakeApiResponse()); }
public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { using (var requestStream = new MemoryStream()) { await MessagePackSerializer.SerializeAsync(requestStream, traces, formatterResolver).ConfigureAwait(false); } return(new FakeApiResponse()); }
public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { // re-create HttpContent on every retry because some versions of HttpClient always dispose of it, so we can't reuse. using (var content = new TracesMessagePackContent(traces, formatterResolver)) { _request.Content = content; var response = await _client.SendAsync(_request).ConfigureAwait(false); return(new HttpClientResponse(response)); } }
public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { _request.Method = "POST"; _request.ContentType = "application/msgpack"; using (var requestStream = await _request.GetRequestStreamAsync().ConfigureAwait(false)) { #if MESSAGEPACK_1_9 await MessagePackSerializer.SerializeAsync(requestStream, traces, formatterResolver).ConfigureAwait(false); #elif MESSAGEPACK_2_1 await MessagePackSerializer.SerializeAsync(requestStream, traces, formatterResolver.Options).ConfigureAwait(false); #endif } var httpWebResponse = (HttpWebResponse)await _request.GetResponseAsync().ConfigureAwait(false); return(new ApiWebResponse(httpWebResponse)); }
public void Serialization() { var tags = new CommonTags(); var span = new Span(new SpanContext(42, 41), DateTimeOffset.UtcNow, tags); // The span has 1 "common" tag and 15 additional tags (and same number of metrics) // Those numbers are picked to test the variable-size header of MessagePack // The header is resized when there are 16 or more elements in the collection // Neither common or additional tags have enough elements, but put together they will cause to use a bigger header tags.Environment = "Test"; tags.SamplingLimitDecision = 0.5; for (int i = 0; i < 15; i++) { span.SetTag(i.ToString(), i.ToString()); } for (int i = 0; i < 15; i++) { span.SetMetric(i.ToString(), i); } var buffer = new byte[0]; var resolver = new FormatterResolverWrapper(SpanFormatterResolver.Instance); MessagePackSerializer.Serialize(ref buffer, 0, span, resolver); var deserializedSpan = MessagePack.MessagePackSerializer.Deserialize <FakeSpan>(buffer); Assert.Equal(16, deserializedSpan.Tags.Count); Assert.Equal(16, deserializedSpan.Metrics.Count); Assert.Equal("Test", deserializedSpan.Tags[Tags.Env]); Assert.Equal(0.5, deserializedSpan.Metrics[Metrics.SamplingLimitDecision]); for (int i = 0; i < 15; i++) { Assert.Equal(i.ToString(), deserializedSpan.Tags[i.ToString()]); Assert.Equal((double)i, deserializedSpan.Metrics[i.ToString()]); } }
public async Task <IApiResponse> PostAsync(Span[][] traces, FormatterResolverWrapper formatterResolver) { _request.Method = "POST"; _request.ContentType = "application/msgpack"; using (var requestStream = await _request.GetRequestStreamAsync().ConfigureAwait(false)) { await CachedSerializer.Instance.SerializeAsync(requestStream, traces, formatterResolver).ConfigureAwait(false); } try { var httpWebResponse = (HttpWebResponse)await _request.GetResponseAsync().ConfigureAwait(false); return(new ApiWebResponse(httpWebResponse)); } catch (WebException exception) when(exception.Status == WebExceptionStatus.ProtocolError && exception.Response != null) { // If the exception is caused by an error status code, ignore it and let the caller handle the result return(new ApiWebResponse((HttpWebResponse)exception.Response)); } }
public void Serialization(bool topLevelSpan) { var tags = new CommonTags(); Span span; if (topLevelSpan) { span = new Span(new SpanContext(42, 41), DateTimeOffset.UtcNow, tags); } else { // Assign a parent to prevent the span from being considered as top-level var traceContext = new TraceContext(Mock.Of <IDatadogTracer>()); var parent = new SpanContext(42, 41); span = new Span(new SpanContext(parent, traceContext, null), DateTimeOffset.UtcNow, tags); } // The span has 1 "common" tag and 15 additional tags (and same number of metrics) // Those numbers are picked to test the variable-size header of MessagePack // The header is resized when there are 16 or more elements in the collection // Neither common or additional tags have enough elements, but put together they will cause to use a bigger header tags.Environment = "Test"; tags.SamplingLimitDecision = 0.5; // Override the properties span.SetTag(Tags.Env, "Overridden Environment"); span.SetMetric(Metrics.SamplingLimitDecision, 0.75); for (int i = 0; i < 15; i++) { span.SetTag(i.ToString(), i.ToString()); } for (int i = 0; i < 15; i++) { span.SetMetric(i.ToString(), i); } var buffer = new byte[0]; var resolver = new FormatterResolverWrapper(SpanFormatterResolver.Instance); MessagePackSerializer.Serialize(ref buffer, 0, span, resolver); var deserializedSpan = MessagePack.MessagePackSerializer.Deserialize <FakeSpan>(buffer); Assert.Equal(16, deserializedSpan.Tags.Count); // For top-level spans, there is one metric added during serialization Assert.Equal(topLevelSpan ? 17 : 16, deserializedSpan.Metrics.Count); Assert.Equal("Overridden Environment", deserializedSpan.Tags[Tags.Env]); Assert.Equal(0.75, deserializedSpan.Metrics[Metrics.SamplingLimitDecision]); for (int i = 0; i < 15; i++) { Assert.Equal(i.ToString(), deserializedSpan.Tags[i.ToString()]); Assert.Equal((double)i, deserializedSpan.Metrics[i.ToString()]); } if (topLevelSpan) { Assert.Equal(1.0, deserializedSpan.Metrics[Metrics.TopLevelSpan]); } }