diff --git a/api/trace/api.go b/api/trace/api.go index 9e0031a08d1..85902429937 100644 --- a/api/trace/api.go +++ b/api/trace/api.go @@ -121,6 +121,9 @@ type Span interface { // Set span attributes SetAttributes(...core.KeyValue) + + // Set singular span attribute, with type inference. + SetAttribute(string, interface{}) } // StartOption applies changes to StartConfig that sets options at span start time. diff --git a/api/trace/context_test.go b/api/trace/context_test.go index 47f6e0341f1..48612db48c5 100644 --- a/api/trace/context_test.go +++ b/api/trace/context_test.go @@ -97,6 +97,10 @@ func (mockSpan) SetError(v bool) { func (mockSpan) SetAttributes(attributes ...core.KeyValue) { } +// SetAttribute does nothing. +func (mockSpan) SetAttribute(k string, v interface{}) { +} + // End does nothing. func (mockSpan) End(options ...trace.EndOption) { } diff --git a/api/trace/noop_span.go b/api/trace/noop_span.go index 03e5e35ec89..f06b44dfff5 100644 --- a/api/trace/noop_span.go +++ b/api/trace/noop_span.go @@ -50,6 +50,10 @@ func (NoopSpan) SetError(v bool) { func (NoopSpan) SetAttributes(attributes ...core.KeyValue) { } +// SetAttribute does nothing. +func (NoopSpan) SetAttribute(k string, v interface{}) { +} + // End does nothing. func (NoopSpan) End(options ...EndOption) { } diff --git a/api/trace/testtrace/span.go b/api/trace/testtrace/span.go index c049e2c6c90..b3f76644e9c 100644 --- a/api/trace/testtrace/span.go +++ b/api/trace/testtrace/span.go @@ -24,6 +24,7 @@ import ( "google.golang.org/grpc/codes" "go.opentelemetry.io/otel/api/core" + "go.opentelemetry.io/otel/api/key" "go.opentelemetry.io/otel/api/trace" ) @@ -177,6 +178,10 @@ func (s *Span) SetAttributes(attrs ...core.KeyValue) { } } +func (s *Span) SetAttribute(k string, v interface{}) { + s.SetAttributes(key.Infer(k, v)) +} + // Name returns the name most recently set on the Span, either at or after creation time. // It cannot be change after End has been called on the Span. func (s *Span) Name() string { diff --git a/bridge/opentracing/internal/mock.go b/bridge/opentracing/internal/mock.go index 1264dce44b8..5f2823cc23f 100644 --- a/bridge/opentracing/internal/mock.go +++ b/bridge/opentracing/internal/mock.go @@ -239,6 +239,10 @@ func (s *MockSpan) SetAttributes(attributes ...otelcore.KeyValue) { }) } +func (s *MockSpan) SetAttribute(k string, v interface{}) { + s.SetAttributes(otelkey.Infer(k, v)) +} + func (s *MockSpan) applyUpdate(update otelcorrelation.MapUpdate) { s.Attributes = s.Attributes.Apply(update) } diff --git a/internal/trace/mock_span.go b/internal/trace/mock_span.go index 732643989d7..89991eee4ba 100644 --- a/internal/trace/mock_span.go +++ b/internal/trace/mock_span.go @@ -59,6 +59,10 @@ func (ms *MockSpan) SetError(v bool) { func (ms *MockSpan) SetAttributes(attributes ...core.KeyValue) { } +// SetAttribute does nothing. +func (ms *MockSpan) SetAttribute(k string, v interface{}) { +} + // End does nothing. func (ms *MockSpan) End(options ...apitrace.EndOption) { } diff --git a/sdk/trace/span.go b/sdk/trace/span.go index 5b9e2bc5df0..b1b1f3873df 100644 --- a/sdk/trace/span.go +++ b/sdk/trace/span.go @@ -24,6 +24,7 @@ import ( "google.golang.org/grpc/codes" "go.opentelemetry.io/otel/api/core" + "go.opentelemetry.io/otel/api/key" apitrace "go.opentelemetry.io/otel/api/trace" export "go.opentelemetry.io/otel/sdk/export/trace" "go.opentelemetry.io/otel/sdk/internal" @@ -100,6 +101,10 @@ func (s *span) SetAttributes(attributes ...core.KeyValue) { s.copyToCappedAttributes(attributes...) } +func (s *span) SetAttribute(k string, v interface{}) { + s.SetAttributes(key.Infer(k, v)) +} + func (s *span) End(options ...apitrace.EndOption) { if s == nil { return