1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2025-07-17 01:12:45 +02:00

Make WithoutTimestamps work (#2195)

* Make WithoutTimestamps work

* Add changes to changelog

Co-authored-by: Tyler Yahn <MrAlias@users.noreply.github.com>
Co-authored-by: Tyler Yahn <codingalias@gmail.com>
This commit is contained in:
Lucas Käldström
2021-08-24 00:29:51 +03:00
committed by GitHub
parent 85c27e016f
commit add511c105
3 changed files with 57 additions and 29 deletions

View File

@ -42,6 +42,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Setting the global `ErrorHandler` with `"go.opentelemetry.io/otel".SetErrorHandler` multiple times is now supported. (#2160, #2140)
- The `"go.opentelemetry.io/otel/attribute".Any` function now supports `int32` values. (#2169)
- Multiple calls to `"go.opentelemetry.io/otel/sdk/metric/controller/basic".WithResource()` are handled correctly, and when no resources are provided `"go.opentelemetry.io/otel/sdk/resource".Default()` is used. (#2120)
- The `WithoutTimestamps` option for the `go.opentelemetry.io/otel/exporters/stdout/stdouttrace` exporter causes the exporter to correctly ommit timestamps. (#2195)
### Security

View File

@ -19,11 +19,14 @@ import (
"encoding/json"
"fmt"
"sync"
"time"
"go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
)
var zeroTime time.Time
// Exporter is an implementation of trace.SpanSyncer that writes spans to stdout.
type traceExporter struct {
config config
@ -44,7 +47,20 @@ func (e *traceExporter) ExportSpans(ctx context.Context, spans []trace.ReadOnlyS
if len(spans) == 0 {
return nil
}
out, err := e.marshal(tracetest.SpanStubsFromReadOnlySpans(spans))
stubs := tracetest.SpanStubsFromReadOnlySpans(spans)
if !e.config.Timestamps {
for i := range stubs {
stub := &stubs[i]
stub.StartTime = zeroTime
stub.EndTime = zeroTime
for j := range stub.Events {
ev := &stub.Events[j]
ev.Time = zeroTime
}
}
}
out, err := e.marshal(stubs)
if err != nil {
return err
}

View File

@ -18,11 +18,11 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/codes"
@ -34,13 +34,6 @@ import (
)
func TestExporter_ExportSpan(t *testing.T) {
// write to buffer for testing
var b bytes.Buffer
ex, err := stdouttrace.New(stdouttrace.WithWriter(&b), stdouttrace.WithPrettyPrint())
if err != nil {
t.Errorf("Error constructing stdout exporter %s", err)
}
// setup test span
now := time.Now()
traceID, _ := trace.TraceIDFromHex("0102030405060708090a0b0c0d0e0f10")
@ -76,14 +69,39 @@ func TestExporter_ExportSpan(t *testing.T) {
Resource: resource,
},
}.Snapshots()
if err := ex.ExportSpans(context.Background(), ro); err != nil {
t.Fatal(err)
tests := []struct {
opts []stdouttrace.Option
expectNow time.Time
}{
{
opts: []stdouttrace.Option{stdouttrace.WithPrettyPrint()},
expectNow: now,
},
{
opts: []stdouttrace.Option{stdouttrace.WithPrettyPrint(), stdouttrace.WithoutTimestamps()},
// expectNow is an empty time.Time
},
}
expectedSerializedNow, _ := json.Marshal(now)
ctx := context.Background()
for _, tt := range tests {
// write to buffer for testing
var b bytes.Buffer
ex, err := stdouttrace.New(append(tt.opts, stdouttrace.WithWriter(&b))...)
require.Nil(t, err)
got := b.String()
expectedOutput := `[
err = ex.ExportSpans(ctx, ro)
require.Nil(t, err)
got := b.String()
assert.Equal(t, expectedJSON(tt.expectNow), got)
}
}
func expectedJSON(now time.Time) string {
serializedNow, _ := json.Marshal(now)
return `[
{
"Name": "/foo",
"SpanContext": {
@ -101,8 +119,8 @@ func TestExporter_ExportSpan(t *testing.T) {
"Remote": false
},
"SpanKind": 1,
"StartTime": ` + string(expectedSerializedNow) + `,
"EndTime": ` + string(expectedSerializedNow) + `,
"StartTime": ` + string(serializedNow) + `,
"EndTime": ` + string(serializedNow) + `,
"Attributes": [
{
"Key": "key",
@ -132,7 +150,7 @@ func TestExporter_ExportSpan(t *testing.T) {
}
],
"DroppedAttributeCount": 0,
"Time": ` + string(expectedSerializedNow) + `
"Time": ` + string(serializedNow) + `
},
{
"Name": "bar",
@ -146,7 +164,7 @@ func TestExporter_ExportSpan(t *testing.T) {
}
],
"DroppedAttributeCount": 0,
"Time": ` + string(expectedSerializedNow) + `
"Time": ` + string(serializedNow) + `
}
],
"Links": null,
@ -175,7 +193,6 @@ func TestExporter_ExportSpan(t *testing.T) {
}
]
`
assert.Equal(t, expectedOutput, got)
}
func TestExporterShutdownHonorsTimeout(t *testing.T) {
@ -190,11 +207,8 @@ func TestExporterShutdownHonorsTimeout(t *testing.T) {
innerCtx, innerCancel := context.WithTimeout(ctx, time.Nanosecond)
defer innerCancel()
<-innerCtx.Done()
if err := e.Shutdown(innerCtx); err == nil {
t.Error("expected context DeadlineExceeded error, got nil")
} else if !errors.Is(err, context.DeadlineExceeded) {
t.Errorf("expected context DeadlineExceeded error, got %v", err)
}
err = e.Shutdown(innerCtx)
assert.ErrorIs(t, err, context.DeadlineExceeded)
}
func TestExporterShutdownHonorsCancel(t *testing.T) {
@ -208,11 +222,8 @@ func TestExporterShutdownHonorsCancel(t *testing.T) {
innerCtx, innerCancel := context.WithCancel(ctx)
innerCancel()
if err := e.Shutdown(innerCtx); err == nil {
t.Error("expected context canceled error, got nil")
} else if !errors.Is(err, context.Canceled) {
t.Errorf("expected context canceled error, got %v", err)
}
err = e.Shutdown(innerCtx)
assert.ErrorIs(t, err, context.Canceled)
}
func TestExporterShutdownNoError(t *testing.T) {