Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add tracing helper #650

Merged
merged 1 commit into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.1
github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf
github.com/instana/go-sensor v1.46.0
github.com/instana/testify v1.6.2-0.20200721153833-94b1851f4d65
github.com/jackc/pgconn v1.13.0
github.com/jackc/pgx/v4 v4.17.2
github.com/jandelgado/gcov2lcov v1.0.5
Expand Down
2 changes: 1 addition & 1 deletion otelx/otel_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"testing"
"time"

"github.com/instana/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/attribute"
"golang.org/x/sync/errgroup"
Expand Down
54 changes: 41 additions & 13 deletions otelx/withspan.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package otelx

import (
"context"
"fmt"

"go.opentelemetry.io/otel/codes"
"go.opentelemetry.io/otel/trace"
Expand All @@ -21,21 +22,48 @@ func WithSpan(ctx context.Context, name string, f func(context.Context) error, o
ctx, span := trace.SpanFromContext(ctx).TracerProvider().Tracer("").Start(ctx, name, opts...)
defer func() {
defer span.End()
if err != nil {
span.SetStatus(codes.Error, err.Error())
} else if r := recover(); r != nil {
switch e := r.(type) {
case error:
span.SetStatus(codes.Error, "panic: "+e.Error())
case interface{ String() string }:
span.SetStatus(codes.Error, "panic: "+e.String())
case string:
span.SetStatus(codes.Error, "panic: "+e)
default:
span.SetStatus(codes.Error, "panic")
}
if r := recover(); r != nil {
setErrorStatusPanic(span, r)
panic(r)
} else if err != nil {
span.SetStatus(codes.Error, err.Error())
}
}()
return f(ctx)
}

// End finishes span, and automatically sets the error state if *err is not nil
// or during panicking.
//
// Usage:
//
// func Divide(ctx context.Context, numerator, denominator int) (ratio int, err error) {
// ctx, span := tracer.Start(ctx, "my-operation")
// defer otelx.End(span, &err)
// if denominator == 0 {
// return 0, errors.New("cannot divide by zero")
// }
// return numerator / denominator, nil
// }
func End(span trace.Span, err *error) {
defer span.End()
if r := recover(); r != nil {
setErrorStatusPanic(span, r)
panic(r)
}
if err == nil || *err == nil {
return
}
span.SetStatus(codes.Error, (*err).Error())
}

func setErrorStatusPanic(span trace.Span, recovered any) {
switch e := recovered.(type) {
case error, string, fmt.Stringer:
span.SetStatus(codes.Error, fmt.Sprintf("panic: %v", e))
default:
span.SetStatus(codes.Error, "panic")
case nil:
// nothing
}
}
47 changes: 45 additions & 2 deletions otelx/withspan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,16 @@ import (
"errors"
"testing"

"github.com/instana/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.opentelemetry.io/otel/codes"
sdktrace "go.opentelemetry.io/otel/sdk/trace"
"go.opentelemetry.io/otel/sdk/trace/tracetest"
"go.opentelemetry.io/otel/trace"
)

var errPanic = errors.New("panic-error")

func TestWithSpan(t *testing.T) {
tracer := trace.NewNoopTracerProvider().Tracer("test")
ctx, span := tracer.Start(context.Background(), "parent")
Expand All @@ -36,4 +42,41 @@ func TestWithSpan(t *testing.T) {
})
}

var errPanic = errors.New("panic-error")
func returnsError(ctx context.Context) (err error) {
_, span := trace.SpanFromContext(ctx).TracerProvider().Tracer("").Start(ctx, "returnsError")
defer End(span, &err)
return errors.New("error from returnsError()")
}

func returnsNamedError(ctx context.Context) (err error) {
ctx, span := trace.SpanFromContext(ctx).TracerProvider().Tracer("").Start(ctx, "returnsNamedError")
defer End(span, &err)
err2 := errors.New("err2 message")
return err2
}

func panics(ctx context.Context) (err error) {
_, span := trace.SpanFromContext(ctx).TracerProvider().Tracer("").Start(ctx, "panics")
defer End(span, &err)
panic(errors.New("panic from panics()"))
}

func TestEnd(t *testing.T) {
recorder := tracetest.NewSpanRecorder()
tracer := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(recorder)).Tracer("test")
ctx, span := tracer.Start(context.Background(), "parent")
defer span.End()

assert.Errorf(t, returnsError(ctx), "error from returnsError()")
require.NotEmpty(t, recorder.Ended())
assert.Equal(t, recorder.Ended()[len(recorder.Ended())-1].Status(), sdktrace.Status{codes.Error, "error from returnsError()"})

assert.Errorf(t, returnsNamedError(ctx), "err2 message")
require.NotEmpty(t, recorder.Ended())
assert.Equal(t, recorder.Ended()[len(recorder.Ended())-1].Status(), sdktrace.Status{codes.Error, "err2 message"})

assert.PanicsWithError(t, "panic from panics()", func() { panics(ctx) })
require.NotEmpty(t, recorder.Ended())
assert.Equal(t, recorder.Ended()[len(recorder.Ended())-1].Status(), sdktrace.Status{codes.Error, "panic: panic from panics()"})

}
2 changes: 1 addition & 1 deletion pagination/keysetpagination/header_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/url"
"testing"

"github.com/instana/testify/assert"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

Expand Down
2 changes: 1 addition & 1 deletion requirex/time_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"testing"
"time"

"github.com/instana/testify/require"
"github.com/stretchr/testify/require"
)

type MockT struct {
Expand Down