You've already forked opentelemetry-go
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:
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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) {
|
||||
|
Reference in New Issue
Block a user