1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2024-12-12 10:04:29 +02:00

chore(zipkin-exporter): relay on the status code for the request but still read the response body. (#1328)

* chore(zipkin-exporter): relay on the status code for the request but still read the response body.

* fix(zipkin-exporter): fix tests.

* chore(zipkin-exporter): adds changelog.

* chore: 202 -> http.StatusAccepted

Co-authored-by: Chris Bandy <bandy.chris@gmail.com>

* chore: 202 -> http.StatusAccepted

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>

Co-authored-by: Chris Bandy <bandy.chris@gmail.com>
Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
This commit is contained in:
José Carlos Chávez 2020-12-03 18:51:09 +01:00 committed by GitHub
parent 66db2d845b
commit 787e3f457a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 14 deletions

View File

@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Move the OpenCensus example into `example` directory. (#1359) - Move the OpenCensus example into `example` directory. (#1359)
- `NewExporter` and `Start` functions in `go.opentelemetry.io/otel/exporters/otlp` now receive `context.Context` as a first parameter. (#1357) - `NewExporter` and `Start` functions in `go.opentelemetry.io/otel/exporters/otlp` now receive `context.Context` as a first parameter. (#1357)
- Zipkin exporter relies on the status code for success rather than body read but still read the response body. (#1328)
## [0.14.0] - 2020-11-19 ## [0.14.0] - 2020-11-19

View File

@ -20,6 +20,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
@ -112,14 +113,14 @@ func NewRawExporter(collectorURL, serviceName string, opts ...Option) (*Exporter
// NewExportPipeline sets up a complete export pipeline // NewExportPipeline sets up a complete export pipeline
// with the recommended setup for trace provider // with the recommended setup for trace provider
func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktrace.TracerProvider, error) { func NewExportPipeline(collectorURL, serviceName string, opts ...Option) (*sdktrace.TracerProvider, error) {
exp, err := NewRawExporter(collectorURL, serviceName, opts...) exporter, err := NewRawExporter(collectorURL, serviceName, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exp)) tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
if exp.o.config != nil { if exporter.o.config != nil {
tp.ApplyConfig(*exp.o.config) tp.ApplyConfig(*exporter.o.config)
} }
return tp, err return tp, err
@ -166,19 +167,21 @@ func (e *Exporter) ExportSpans(ctx context.Context, batch []*export.SpanData) er
if err != nil { if err != nil {
return e.errf("request to %s failed: %v", e.url, err) return e.errf("request to %s failed: %v", e.url, err)
} }
e.logf("zipkin responded with status %d", resp.StatusCode) defer resp.Body.Close()
_, err = ioutil.ReadAll(resp.Body) // Zipkin API returns a 202 on success and the content of the body isn't interesting
// but it is still being read because according to https://golang.org/pkg/net/http/#Response
// > The default HTTP client's Transport may not reuse HTTP/1.x "keep-alive" TCP connections
// > if the Body is not read to completion and closed.
_, err = io.Copy(ioutil.Discard, resp.Body)
if err != nil { if err != nil {
// Best effort to clean up here.
resp.Body.Close()
return e.errf("failed to read response body: %v", err) return e.errf("failed to read response body: %v", err)
} }
err = resp.Body.Close() if resp.StatusCode != http.StatusAccepted {
if err != nil { return e.errf("failed to send spans to zipkin server with status %d", resp.StatusCode)
return e.errf("failed to close response body: %v", err)
} }
return nil return nil
} }

View File

@ -192,6 +192,7 @@ func (c *mockZipkinCollector) handler(w http.ResponseWriter, r *http.Request) {
c.lock.Lock() c.lock.Lock()
defer c.lock.Unlock() defer c.lock.Unlock()
c.models = append(c.models, models...) c.models = append(c.models, models...)
w.WriteHeader(http.StatusAccepted)
} }
func (c *mockZipkinCollector) Close() { func (c *mockZipkinCollector) Close() {
@ -340,9 +341,8 @@ func TestExportSpans(t *testing.T) {
ctx := context.Background() ctx := context.Background()
require.Len(t, ls.Messages, 0) require.Len(t, ls.Messages, 0)
require.NoError(t, exporter.ExportSpans(ctx, spans[0:1])) require.NoError(t, exporter.ExportSpans(ctx, spans[0:1]))
require.Len(t, ls.Messages, 2) require.Len(t, ls.Messages, 1)
require.Contains(t, ls.Messages[0], "send a POST request") require.Contains(t, ls.Messages[0], "send a POST request")
require.Contains(t, ls.Messages[1], "zipkin responded")
ls.Messages = nil ls.Messages = nil
require.NoError(t, exporter.ExportSpans(ctx, nil)) require.NoError(t, exporter.ExportSpans(ctx, nil))
require.Len(t, ls.Messages, 1) require.Len(t, ls.Messages, 1)
@ -350,7 +350,6 @@ func TestExportSpans(t *testing.T) {
ls.Messages = nil ls.Messages = nil
require.NoError(t, exporter.ExportSpans(ctx, spans[1:2])) require.NoError(t, exporter.ExportSpans(ctx, spans[1:2]))
require.Contains(t, ls.Messages[0], "send a POST request") require.Contains(t, ls.Messages[0], "send a POST request")
require.Contains(t, ls.Messages[1], "zipkin responded")
checkFunc := func() bool { checkFunc := func() bool {
return collector.ModelsLen() == len(models) return collector.ModelsLen() == len(models)
} }