You've already forked opentelemetry-go
mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-07-15 01:04:25 +02:00
Add status message parameter (#524)
* Add status message parameter * Cleanups around use of codes.OK * Update for status message
This commit is contained in:
@ -323,7 +323,7 @@ func (h *Harness) testSpan(tracerFactory func() trace.Tracer) {
|
|||||||
span.AddEventWithTimestamp(context.Background(), time.Now(), "test event")
|
span.AddEventWithTimestamp(context.Background(), time.Now(), "test event")
|
||||||
},
|
},
|
||||||
"#SetStatus": func(span trace.Span) {
|
"#SetStatus": func(span trace.Span) {
|
||||||
span.SetStatus(codes.Internal)
|
span.SetStatus(codes.Internal, "internal")
|
||||||
},
|
},
|
||||||
"#SetName": func(span trace.Span) {
|
"#SetName": func(span trace.Span) {
|
||||||
span.SetName("new name")
|
span.SetName("new name")
|
||||||
|
@ -62,8 +62,8 @@ func WithEndTime(t time.Time) EndOption {
|
|||||||
|
|
||||||
// ErrorConfig provides options to set properties of an error event at the time it is recorded.
|
// ErrorConfig provides options to set properties of an error event at the time it is recorded.
|
||||||
type ErrorConfig struct {
|
type ErrorConfig struct {
|
||||||
Timestamp time.Time
|
Timestamp time.Time
|
||||||
Status codes.Code
|
StatusCode codes.Code
|
||||||
}
|
}
|
||||||
|
|
||||||
// ErrorOption applies changes to ErrorConfig that sets options when an error event is recorded.
|
// ErrorOption applies changes to ErrorConfig that sets options when an error event is recorded.
|
||||||
@ -79,7 +79,7 @@ func WithErrorTime(t time.Time) ErrorOption {
|
|||||||
// WithErrorStatus indicates the span status that should be set when recording an error event.
|
// WithErrorStatus indicates the span status that should be set when recording an error event.
|
||||||
func WithErrorStatus(s codes.Code) ErrorOption {
|
func WithErrorStatus(s codes.Code) ErrorOption {
|
||||||
return func(c *ErrorConfig) {
|
return func(c *ErrorConfig) {
|
||||||
c.Status = s
|
c.StatusCode = s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,9 +107,14 @@ type Span interface {
|
|||||||
// even after the span ends.
|
// even after the span ends.
|
||||||
SpanContext() core.SpanContext
|
SpanContext() core.SpanContext
|
||||||
|
|
||||||
// SetStatus sets the status of the span. The status of the span can be updated
|
// SetStatus sets the status of the span in the form of a code
|
||||||
// even after span ends.
|
// and a message. SetStatus overrides the value of previous
|
||||||
SetStatus(codes.Code)
|
// calls to SetStatus on the Span.
|
||||||
|
//
|
||||||
|
// The default span status is OK, so it is not necessary to
|
||||||
|
// explicitly set an OK status on successful Spans unless it
|
||||||
|
// is to add an OK message or to override a previous status on the Span.
|
||||||
|
SetStatus(codes.Code, string)
|
||||||
|
|
||||||
// SetName sets the name of the span.
|
// SetName sets the name of the span.
|
||||||
SetName(name string)
|
SetName(name string)
|
||||||
|
@ -68,7 +68,7 @@ func (mockSpan) IsRecording() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetStatus does nothing.
|
// SetStatus does nothing.
|
||||||
func (mockSpan) SetStatus(status codes.Code) {
|
func (mockSpan) SetStatus(status codes.Code, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetName does nothing.
|
// SetName does nothing.
|
||||||
|
@ -39,7 +39,7 @@ func (NoopSpan) IsRecording() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetStatus does nothing.
|
// SetStatus does nothing.
|
||||||
func (NoopSpan) SetStatus(status codes.Code) {
|
func (NoopSpan) SetStatus(status codes.Code, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetError does nothing.
|
// SetError does nothing.
|
||||||
|
@ -36,18 +36,19 @@ const (
|
|||||||
var _ trace.Span = (*Span)(nil)
|
var _ trace.Span = (*Span)(nil)
|
||||||
|
|
||||||
type Span struct {
|
type Span struct {
|
||||||
lock *sync.RWMutex
|
lock *sync.RWMutex
|
||||||
tracer *Tracer
|
tracer *Tracer
|
||||||
spanContext core.SpanContext
|
spanContext core.SpanContext
|
||||||
parentSpanID core.SpanID
|
parentSpanID core.SpanID
|
||||||
ended bool
|
ended bool
|
||||||
name string
|
name string
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
endTime time.Time
|
endTime time.Time
|
||||||
status codes.Code
|
statusCode codes.Code
|
||||||
attributes map[core.Key]core.Value
|
statusMessage string
|
||||||
events []Event
|
attributes map[core.Key]core.Value
|
||||||
links map[core.SpanContext][]core.KeyValue
|
events []Event
|
||||||
|
links map[core.SpanContext][]core.KeyValue
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Span) Tracer() trace.Tracer {
|
func (s *Span) Tracer() trace.Tracer {
|
||||||
@ -91,8 +92,8 @@ func (s *Span) RecordError(ctx context.Context, err error, opts ...trace.ErrorOp
|
|||||||
cfg.Timestamp = time.Now()
|
cfg.Timestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Status != codes.OK {
|
if cfg.StatusCode != codes.OK {
|
||||||
s.SetStatus(cfg.Status)
|
s.SetStatus(cfg.StatusCode, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
errType := reflect.TypeOf(err)
|
errType := reflect.TypeOf(err)
|
||||||
@ -140,7 +141,7 @@ func (s *Span) SpanContext() core.SpanContext {
|
|||||||
return s.spanContext
|
return s.spanContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Span) SetStatus(status codes.Code) {
|
func (s *Span) SetStatus(code codes.Code, msg string) {
|
||||||
s.lock.Lock()
|
s.lock.Lock()
|
||||||
defer s.lock.Unlock()
|
defer s.lock.Unlock()
|
||||||
|
|
||||||
@ -148,7 +149,8 @@ func (s *Span) SetStatus(status codes.Code) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
s.status = status
|
s.statusCode = code
|
||||||
|
s.statusMessage = msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Span) SetName(name string) {
|
func (s *Span) SetName(name string) {
|
||||||
@ -245,6 +247,12 @@ func (s *Span) Ended() bool {
|
|||||||
// Status returns the status most recently set on the Span,
|
// Status returns the status most recently set on the Span,
|
||||||
// or codes.OK if no status has been explicitly set.
|
// or codes.OK if no status has been explicitly set.
|
||||||
// It cannot be changed after End has been called on the Span.
|
// It cannot be changed after End has been called on the Span.
|
||||||
func (s *Span) Status() codes.Code {
|
func (s *Span) StatusCode() codes.Code {
|
||||||
return s.status
|
return s.statusCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// StatusMessage returns the status message most recently set on the
|
||||||
|
// Span or the empty string if no status mesaage was set.
|
||||||
|
func (s *Span) StatusMessage() string {
|
||||||
|
return s.statusMessage
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ package testtrace_test
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -164,7 +165,8 @@ func TestSpan(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
e.Expect(subject.Events()).ToEqual(expectedEvents)
|
e.Expect(subject.Events()).ToEqual(expectedEvents)
|
||||||
e.Expect(subject.Status()).ToEqual(codes.OK)
|
e.Expect(subject.StatusCode()).ToEqual(codes.OK)
|
||||||
|
e.Expect(subject.StatusMessage()).ToEqual("")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -182,8 +184,8 @@ func TestSpan(t *testing.T) {
|
|||||||
errMsg := "test error message"
|
errMsg := "test error message"
|
||||||
testErr := ottest.NewTestError(errMsg)
|
testErr := ottest.NewTestError(errMsg)
|
||||||
testTime := time.Now()
|
testTime := time.Now()
|
||||||
expStatus := codes.Unknown
|
expStatusCode := codes.Unknown
|
||||||
subject.RecordError(ctx, testErr, trace.WithErrorTime(testTime), trace.WithErrorStatus(expStatus))
|
subject.RecordError(ctx, testErr, trace.WithErrorTime(testTime), trace.WithErrorStatus(expStatusCode))
|
||||||
|
|
||||||
expectedEvents := []testtrace.Event{{
|
expectedEvents := []testtrace.Event{{
|
||||||
Timestamp: testTime,
|
Timestamp: testTime,
|
||||||
@ -194,7 +196,7 @@ func TestSpan(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
e.Expect(subject.Events()).ToEqual(expectedEvents)
|
e.Expect(subject.Events()).ToEqual(expectedEvents)
|
||||||
e.Expect(subject.Status()).ToEqual(expStatus)
|
e.Expect(subject.StatusCode()).ToEqual(expStatusCode)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("cannot be set after the span has ended", func(t *testing.T) {
|
t.Run("cannot be set after the span has ended", func(t *testing.T) {
|
||||||
@ -527,11 +529,11 @@ func TestSpan(t *testing.T) {
|
|||||||
subject, ok := span.(*testtrace.Span)
|
subject, ok := span.(*testtrace.Span)
|
||||||
e.Expect(ok).ToBeTrue()
|
e.Expect(ok).ToBeTrue()
|
||||||
|
|
||||||
e.Expect(subject.Status()).ToEqual(codes.OK)
|
e.Expect(subject.StatusCode()).ToEqual(codes.OK)
|
||||||
|
|
||||||
subject.End()
|
subject.End()
|
||||||
|
|
||||||
e.Expect(subject.Status()).ToEqual(codes.OK)
|
e.Expect(subject.StatusCode()).ToEqual(codes.OK)
|
||||||
})
|
})
|
||||||
|
|
||||||
statuses := []codes.Code{
|
statuses := []codes.Code{
|
||||||
@ -566,10 +568,11 @@ func TestSpan(t *testing.T) {
|
|||||||
subject, ok := span.(*testtrace.Span)
|
subject, ok := span.(*testtrace.Span)
|
||||||
e.Expect(ok).ToBeTrue()
|
e.Expect(ok).ToBeTrue()
|
||||||
|
|
||||||
subject.SetStatus(codes.OK)
|
subject.SetStatus(codes.OK, "OK")
|
||||||
subject.SetStatus(status)
|
subject.SetStatus(status, "Yo!")
|
||||||
|
|
||||||
e.Expect(subject.Status()).ToEqual(status)
|
e.Expect(subject.StatusCode()).ToEqual(status)
|
||||||
|
e.Expect(subject.StatusMessage()).ToEqual("Yo!")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
|
t.Run("cannot be changed after the span has been ended", func(t *testing.T) {
|
||||||
@ -585,11 +588,12 @@ func TestSpan(t *testing.T) {
|
|||||||
|
|
||||||
originalStatus := codes.OK
|
originalStatus := codes.OK
|
||||||
|
|
||||||
subject.SetStatus(originalStatus)
|
subject.SetStatus(originalStatus, "OK")
|
||||||
subject.End()
|
subject.End()
|
||||||
subject.SetStatus(status)
|
subject.SetStatus(status, fmt.Sprint(status))
|
||||||
|
|
||||||
e.Expect(subject.Status()).ToEqual(originalStatus)
|
e.Expect(subject.StatusCode()).ToEqual(originalStatus)
|
||||||
|
e.Expect(subject.StatusMessage()).ToEqual("OK")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -124,12 +124,8 @@ func (s *bridgeSpan) SetTag(key string, value interface{}) ot.Span {
|
|||||||
case string(otext.SpanKind):
|
case string(otext.SpanKind):
|
||||||
// TODO: Should we ignore it?
|
// TODO: Should we ignore it?
|
||||||
case string(otext.Error):
|
case string(otext.Error):
|
||||||
if b, ok := value.(bool); ok {
|
if b, ok := value.(bool); ok && b {
|
||||||
status := codes.OK
|
s.otelSpan.SetStatus(codes.Unknown, "")
|
||||||
if b {
|
|
||||||
status = codes.Unknown
|
|
||||||
}
|
|
||||||
s.otelSpan.SetStatus(status)
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
s.otelSpan.SetAttributes(otTagToOtelCoreKeyValue(key, value))
|
s.otelSpan.SetAttributes(otTagToOtelCoreKeyValue(key, value))
|
||||||
@ -330,7 +326,7 @@ func (t *BridgeTracer) StartSpan(operationName string, opts ...ot.StartSpanOptio
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
if hadTrueErrorTag {
|
if hadTrueErrorTag {
|
||||||
otelSpan.SetStatus(codes.Unknown)
|
otelSpan.SetStatus(codes.Unknown, "")
|
||||||
}
|
}
|
||||||
// One does not simply pass a concrete pointer to function
|
// One does not simply pass a concrete pointer to function
|
||||||
// that takes some interface. In case of passing nil concrete
|
// that takes some interface. In case of passing nil concrete
|
||||||
|
@ -33,11 +33,12 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ComponentKey = otelkey.New("component")
|
ComponentKey = otelkey.New("component")
|
||||||
ServiceKey = otelkey.New("service")
|
ServiceKey = otelkey.New("service")
|
||||||
StatusKey = otelkey.New("status")
|
StatusCodeKey = otelkey.New("status.code")
|
||||||
ErrorKey = otelkey.New("error")
|
StatusMessageKey = otelkey.New("status.message")
|
||||||
NameKey = otelkey.New("name")
|
ErrorKey = otelkey.New("error")
|
||||||
|
NameKey = otelkey.New("name")
|
||||||
)
|
)
|
||||||
|
|
||||||
type MockContextKeyValue struct {
|
type MockContextKeyValue struct {
|
||||||
@ -220,8 +221,8 @@ func (s *MockSpan) IsRecording() bool {
|
|||||||
return s.recording
|
return s.recording
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MockSpan) SetStatus(status codes.Code) {
|
func (s *MockSpan) SetStatus(code codes.Code, msg string) {
|
||||||
s.SetAttributes(NameKey.Uint32(uint32(status)))
|
s.SetAttributes(StatusCodeKey.Uint32(uint32(code)), StatusMessageKey.String(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MockSpan) SetName(name string) {
|
func (s *MockSpan) SetName(name string) {
|
||||||
@ -279,8 +280,8 @@ func (s *MockSpan) RecordError(ctx context.Context, err error, opts ...oteltrace
|
|||||||
cfg.Timestamp = time.Now()
|
cfg.Timestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Status != codes.OK {
|
if cfg.StatusCode != codes.OK {
|
||||||
s.SetStatus(cfg.Status)
|
s.SetStatus(cfg.StatusCode, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.AddEventWithTimestamp(ctx, cfg.Timestamp, "error",
|
s.AddEventWithTimestamp(ctx, cfg.Timestamp, "error",
|
||||||
|
@ -22,7 +22,6 @@ import (
|
|||||||
"go.opentelemetry.io/otel/plugin/grpctrace"
|
"go.opentelemetry.io/otel/plugin/grpctrace"
|
||||||
|
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
|
|
||||||
@ -81,8 +80,6 @@ func UnaryClientInterceptor(ctx context.Context, method string, req, reply inter
|
|||||||
func setTraceStatus(ctx context.Context, err error) {
|
func setTraceStatus(ctx context.Context, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s, _ := status.FromError(err)
|
s, _ := status.FromError(err)
|
||||||
trace.SpanFromContext(ctx).SetStatus(s.Code())
|
trace.SpanFromContext(ctx).SetStatus(s.Code(), s.Message())
|
||||||
} else {
|
|
||||||
trace.SpanFromContext(ctx).SetStatus(codes.OK)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,12 +23,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
|
||||||
|
|
||||||
"go.opentelemetry.io/otel/api/correlation"
|
"go.opentelemetry.io/otel/api/correlation"
|
||||||
"go.opentelemetry.io/otel/api/global"
|
"go.opentelemetry.io/otel/api/global"
|
||||||
"go.opentelemetry.io/otel/api/key"
|
"go.opentelemetry.io/otel/api/key"
|
||||||
"go.opentelemetry.io/otel/api/trace"
|
|
||||||
"go.opentelemetry.io/otel/exporters/trace/stdout"
|
"go.opentelemetry.io/otel/exporters/trace/stdout"
|
||||||
"go.opentelemetry.io/otel/plugin/httptrace"
|
"go.opentelemetry.io/otel/plugin/httptrace"
|
||||||
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
sdktrace "go.opentelemetry.io/otel/sdk/trace"
|
||||||
@ -77,7 +74,6 @@ func main() {
|
|||||||
}
|
}
|
||||||
body, err = ioutil.ReadAll(res.Body)
|
body, err = ioutil.ReadAll(res.Body)
|
||||||
_ = res.Body.Close()
|
_ = res.Body.Close()
|
||||||
trace.SpanFromContext(ctx).SetStatus(codes.OK)
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,4 @@ go 1.13
|
|||||||
|
|
||||||
replace go.opentelemetry.io/otel => ../..
|
replace go.opentelemetry.io/otel => ../..
|
||||||
|
|
||||||
require (
|
require go.opentelemetry.io/otel v0.2.3
|
||||||
go.opentelemetry.io/otel v0.2.3
|
|
||||||
google.golang.org/grpc v1.27.1
|
|
||||||
)
|
|
||||||
|
@ -37,7 +37,7 @@ func otSpanToProtoSpan(sd *export.SpanData) *tracepb.Span {
|
|||||||
TraceId: sd.SpanContext.TraceID[:],
|
TraceId: sd.SpanContext.TraceID[:],
|
||||||
SpanId: sd.SpanContext.SpanID[:],
|
SpanId: sd.SpanContext.SpanID[:],
|
||||||
ParentSpanId: sd.ParentSpanID[:],
|
ParentSpanId: sd.ParentSpanID[:],
|
||||||
Status: otStatusToProtoStatus(sd.Status),
|
Status: otStatusToProtoStatus(sd.StatusCode, sd.StatusMessage),
|
||||||
StartTimeUnixnano: uint64(sd.StartTime.Nanosecond()),
|
StartTimeUnixnano: uint64(sd.StartTime.Nanosecond()),
|
||||||
EndTimeUnixnano: uint64(sd.EndTime.Nanosecond()),
|
EndTimeUnixnano: uint64(sd.EndTime.Nanosecond()),
|
||||||
Links: otLinksToProtoLinks(sd.Links),
|
Links: otLinksToProtoLinks(sd.Links),
|
||||||
@ -52,10 +52,10 @@ func otSpanToProtoSpan(sd *export.SpanData) *tracepb.Span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func otStatusToProtoStatus(status codes.Code) *tracepb.Status {
|
func otStatusToProtoStatus(status codes.Code, message string) *tracepb.Status {
|
||||||
return &tracepb.Status{
|
return &tracepb.Status{
|
||||||
Code: tracepb.Status_StatusCode(status),
|
Code: tracepb.Status_StatusCode(status),
|
||||||
// TODO (rghetia) : Add Status Message: when supported.
|
Message: message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,8 @@ func TestOtSpanToOtlpSpan_Basic(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Status: codes.Internal,
|
StatusCode: codes.Internal,
|
||||||
|
StatusMessage: "utterly unrecognized",
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
Attributes: []core.KeyValue{
|
Attributes: []core.KeyValue{
|
||||||
core.Key("timeout_ns").Int64(12e9),
|
core.Key("timeout_ns").Int64(12e9),
|
||||||
@ -109,7 +110,8 @@ func TestOtSpanToOtlpSpan_Basic(t *testing.T) {
|
|||||||
StartTimeUnixnano: uint64(startTime.Nanosecond()),
|
StartTimeUnixnano: uint64(startTime.Nanosecond()),
|
||||||
EndTimeUnixnano: uint64(endTime.Nanosecond()),
|
EndTimeUnixnano: uint64(endTime.Nanosecond()),
|
||||||
Status: &tracepb.Status{
|
Status: &tracepb.Status{
|
||||||
Code: 13,
|
Code: 13,
|
||||||
|
Message: "utterly unrecognized",
|
||||||
},
|
},
|
||||||
Events: []*tracepb.Span_Event{
|
Events: []*tracepb.Span_Event{
|
||||||
{
|
{
|
||||||
|
@ -157,14 +157,15 @@ func spanDataToThrift(data *export.SpanData) *gen.Span {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = append(tags, getInt64Tag("status.code", int64(data.Status)),
|
tags = append(tags,
|
||||||
getStringTag("status.message", data.Status.String()),
|
getInt64Tag("status.code", int64(data.StatusCode)),
|
||||||
|
getStringTag("status.message", data.StatusMessage),
|
||||||
getStringTag("span.kind", data.SpanKind.String()),
|
getStringTag("span.kind", data.SpanKind.String()),
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ensure that if Status.Code is not OK, that we set the "error" tag on the Jaeger span.
|
// Ensure that if Status.Code is not OK, that we set the "error" tag on the Jaeger span.
|
||||||
// See Issue https://github.com/census-instrumentation/opencensus-go/issues/1041
|
// See Issue https://github.com/census-instrumentation/opencensus-go/issues/1041
|
||||||
if data.Status != codes.OK {
|
if data.StatusCode != codes.OK {
|
||||||
tags = append(tags, getBoolTag("error", true))
|
tags = append(tags, getBoolTag("error", true))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ func Test_spanDataToThrift(t *testing.T) {
|
|||||||
statusCodeValue := int64(2)
|
statusCodeValue := int64(2)
|
||||||
doubleValue := 123.456
|
doubleValue := 123.456
|
||||||
boolTrue := true
|
boolTrue := true
|
||||||
statusMessage := "Unknown"
|
statusMessage := "this is a problem"
|
||||||
spanKind := "client"
|
spanKind := "client"
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
@ -192,8 +192,9 @@ func Test_spanDataToThrift(t *testing.T) {
|
|||||||
MessageEvents: []export.Event{
|
MessageEvents: []export.Event{
|
||||||
{Name: eventNameValue, Attributes: []core.KeyValue{key.String("k1", keyValue)}, Time: now},
|
{Name: eventNameValue, Attributes: []core.KeyValue{key.String("k1", keyValue)}, Time: now},
|
||||||
},
|
},
|
||||||
Status: codes.Unknown,
|
StatusCode: codes.Unknown,
|
||||||
SpanKind: apitrace.SpanKindClient,
|
StatusMessage: statusMessage,
|
||||||
|
SpanKind: apitrace.SpanKindClient,
|
||||||
},
|
},
|
||||||
want: &gen.Span{
|
want: &gen.Span{
|
||||||
TraceIdLow: 651345242494996240,
|
TraceIdLow: 651345242494996240,
|
||||||
|
@ -60,8 +60,9 @@ func TestExporter_ExportSpan(t *testing.T) {
|
|||||||
{Name: "foo", Attributes: []core.KeyValue{key.String("key", keyValue)}, Time: now},
|
{Name: "foo", Attributes: []core.KeyValue{key.String("key", keyValue)}, Time: now},
|
||||||
{Name: "bar", Attributes: []core.KeyValue{key.Float64("double", doubleValue)}, Time: now},
|
{Name: "bar", Attributes: []core.KeyValue{key.Float64("double", doubleValue)}, Time: now},
|
||||||
},
|
},
|
||||||
SpanKind: trace.SpanKindInternal,
|
SpanKind: trace.SpanKindInternal,
|
||||||
Status: codes.Unknown,
|
StatusCode: codes.Unknown,
|
||||||
|
StatusMessage: "interesting",
|
||||||
}
|
}
|
||||||
ex.ExportSpan(context.Background(), testSpan)
|
ex.ExportSpan(context.Background(), testSpan)
|
||||||
|
|
||||||
@ -109,7 +110,8 @@ func TestExporter_ExportSpan(t *testing.T) {
|
|||||||
`}` +
|
`}` +
|
||||||
`],` +
|
`],` +
|
||||||
`"Links":null,` +
|
`"Links":null,` +
|
||||||
`"Status":2,` +
|
`"StatusCode":2,` +
|
||||||
|
`"StatusMessage":"interesting",` +
|
||||||
`"HasRemoteParent":false,` +
|
`"HasRemoteParent":false,` +
|
||||||
`"DroppedAttributeCount":0,` +
|
`"DroppedAttributeCount":0,` +
|
||||||
`"DroppedMessageEventCount":0,` +
|
`"DroppedMessageEventCount":0,` +
|
||||||
|
@ -47,7 +47,7 @@ func (ms *MockSpan) IsRecording() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SetStatus does nothing.
|
// SetStatus does nothing.
|
||||||
func (ms *MockSpan) SetStatus(status codes.Code) {
|
func (ms *MockSpan) SetStatus(status codes.Code, msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetError does nothing.
|
// SetError does nothing.
|
||||||
|
@ -35,7 +35,6 @@ var (
|
|||||||
HTTPHeaderMIME = key.New("http.mime")
|
HTTPHeaderMIME = key.New("http.mime")
|
||||||
HTTPRemoteAddr = key.New("http.remote")
|
HTTPRemoteAddr = key.New("http.remote")
|
||||||
HTTPLocalAddr = key.New("http.local")
|
HTTPLocalAddr = key.New("http.local")
|
||||||
MessageKey = key.New("message")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type clientTracer struct {
|
type clientTracer struct {
|
||||||
@ -97,8 +96,7 @@ func (ct *clientTracer) end(hook string, err error, attrs ...core.KeyValue) {
|
|||||||
defer ct.mtx.Unlock()
|
defer ct.mtx.Unlock()
|
||||||
if span, ok := ct.activeHooks[hook]; ok {
|
if span, ok := ct.activeHooks[hook]; ok {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
span.SetStatus(codes.Unknown)
|
span.SetStatus(codes.Unknown, err.Error())
|
||||||
span.SetAttributes(MessageKey.String(err.Error()))
|
|
||||||
}
|
}
|
||||||
span.SetAttributes(attrs...)
|
span.SetAttributes(attrs...)
|
||||||
span.End()
|
span.End()
|
||||||
@ -172,8 +170,7 @@ func (ct *clientTracer) wroteHeaders() {
|
|||||||
|
|
||||||
func (ct *clientTracer) wroteRequest(info httptrace.WroteRequestInfo) {
|
func (ct *clientTracer) wroteRequest(info httptrace.WroteRequestInfo) {
|
||||||
if info.Err != nil {
|
if info.Err != nil {
|
||||||
ct.root.SetAttributes(MessageKey.String(info.Err.Error()))
|
ct.root.SetStatus(codes.Unknown, info.Err.Error())
|
||||||
ct.root.SetStatus(codes.Unknown)
|
|
||||||
}
|
}
|
||||||
ct.end("http.send", info.Err)
|
ct.end("http.send", info.Err)
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,8 @@ type SpanData struct {
|
|||||||
Attributes []core.KeyValue
|
Attributes []core.KeyValue
|
||||||
MessageEvents []Event
|
MessageEvents []Event
|
||||||
Links []apitrace.Link
|
Links []apitrace.Link
|
||||||
Status codes.Code
|
StatusCode codes.Code
|
||||||
|
StatusMessage string
|
||||||
HasRemoteParent bool
|
HasRemoteParent bool
|
||||||
DroppedAttributeCount int
|
DroppedAttributeCount int
|
||||||
DroppedMessageEventCount int
|
DroppedMessageEventCount int
|
||||||
|
@ -80,7 +80,7 @@ func (s *span) IsRecording() bool {
|
|||||||
return s.data != nil
|
return s.data != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *span) SetStatus(status codes.Code) {
|
func (s *span) SetStatus(code codes.Code, msg string) {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -88,7 +88,8 @@ func (s *span) SetStatus(status codes.Code) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.mu.Lock()
|
s.mu.Lock()
|
||||||
s.data.Status = status
|
s.data.StatusCode = code
|
||||||
|
s.data.StatusMessage = msg
|
||||||
s.mu.Unlock()
|
s.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,8 +151,8 @@ func (s *span) RecordError(ctx context.Context, err error, opts ...apitrace.Erro
|
|||||||
cfg.Timestamp = time.Now()
|
cfg.Timestamp = time.Now()
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Status != codes.OK {
|
if cfg.StatusCode != codes.OK {
|
||||||
s.SetStatus(cfg.Status)
|
s.SetStatus(cfg.StatusCode, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
errType := reflect.TypeOf(err)
|
errType := reflect.TypeOf(err)
|
||||||
|
@ -559,7 +559,7 @@ func TestSetSpanStatus(t *testing.T) {
|
|||||||
tp, _ := NewProvider(WithSyncer(te))
|
tp, _ := NewProvider(WithSyncer(te))
|
||||||
|
|
||||||
span := startSpan(tp, "SpanStatus")
|
span := startSpan(tp, "SpanStatus")
|
||||||
span.SetStatus(codes.Canceled)
|
span.SetStatus(codes.Canceled, "canceled")
|
||||||
got, err := endSpan(te, span)
|
got, err := endSpan(te, span)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -573,7 +573,8 @@ func TestSetSpanStatus(t *testing.T) {
|
|||||||
ParentSpanID: sid,
|
ParentSpanID: sid,
|
||||||
Name: "span0",
|
Name: "span0",
|
||||||
SpanKind: apitrace.SpanKindInternal,
|
SpanKind: apitrace.SpanKindInternal,
|
||||||
Status: codes.Canceled,
|
StatusCode: codes.Canceled,
|
||||||
|
StatusMessage: "canceled",
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
}
|
}
|
||||||
if diff := cmpDiff(got, want); diff != "" {
|
if diff := cmpDiff(got, want); diff != "" {
|
||||||
@ -957,7 +958,8 @@ func TestRecordErrorWithStatus(t *testing.T) {
|
|||||||
ParentSpanID: sid,
|
ParentSpanID: sid,
|
||||||
Name: "span0",
|
Name: "span0",
|
||||||
SpanKind: apitrace.SpanKindInternal,
|
SpanKind: apitrace.SpanKindInternal,
|
||||||
Status: codes.Unknown,
|
StatusCode: codes.Unknown,
|
||||||
|
StatusMessage: "",
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
MessageEvents: []export.Event{
|
MessageEvents: []export.Event{
|
||||||
{
|
{
|
||||||
@ -996,7 +998,8 @@ func TestRecordErrorNil(t *testing.T) {
|
|||||||
Name: "span0",
|
Name: "span0",
|
||||||
SpanKind: apitrace.SpanKindInternal,
|
SpanKind: apitrace.SpanKindInternal,
|
||||||
HasRemoteParent: true,
|
HasRemoteParent: true,
|
||||||
Status: codes.OK,
|
StatusCode: codes.OK,
|
||||||
|
StatusMessage: "",
|
||||||
}
|
}
|
||||||
if diff := cmpDiff(got, want); diff != "" {
|
if diff := cmpDiff(got, want); diff != "" {
|
||||||
t.Errorf("SpanErrorOptions: -got +want %s", diff)
|
t.Errorf("SpanErrorOptions: -got +want %s", diff)
|
||||||
|
Reference in New Issue
Block a user