mirror of
https://github.com/open-telemetry/opentelemetry-go.git
synced 2025-04-23 11:58:56 +02:00
Add instrumentation scope attributes (#3131)
* Add WithScopeAttributes TracerOption to trace API * Add Attributes field to instrumentation Scope * Use scope attributes for new Tracer * Fix stdouttrace expected test output * Allow unexported Set fields in sdk/trace test * Export instrumentation scope attrs in OTLP * Add changes to the changelog * Fix imports with make lint * Add unit tests for WithScopeAttributes * Fix English in Scope documentation
This commit is contained in:
parent
454d57b720
commit
0078faeb0e
@ -13,6 +13,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
- Support Go 1.19.
|
- Support Go 1.19.
|
||||||
Include compatibility testing and document support. (#3077)
|
Include compatibility testing and document support. (#3077)
|
||||||
- Upgrade go.opentelemetry.io/proto/otlp from v0.18.0 to v0.19.0 (#3107)
|
- Upgrade go.opentelemetry.io/proto/otlp from v0.18.0 to v0.19.0 (#3107)
|
||||||
|
- Add an `Attribute` field to the `Scope` type in `go.opentelemetry.io/otel/sdk/instrumentation`. (#3131)
|
||||||
|
- Add the `WithScopeAttributes` `TracerOption` to the `go.opentelemetry.io/otel/trace` package. (#3131)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
@ -21,6 +23,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|||||||
exact upper-inclusive boundary support following the [corresponding
|
exact upper-inclusive boundary support following the [corresponding
|
||||||
specification change](https://github.com/open-telemetry/opentelemetry-specification/pull/2633). (#2982)
|
specification change](https://github.com/open-telemetry/opentelemetry-specification/pull/2633). (#2982)
|
||||||
- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110)
|
- Attempting to start a span with a nil `context` will no longer cause a panic. (#3110)
|
||||||
|
- Export scope attributes for all exporters provided by `go.opentelemetry.io/otel/exporters/otlp/otlptrace`. (#3131)
|
||||||
|
|
||||||
## [1.9.0/0.0.3] - 2022-08-01
|
## [1.9.0/0.0.3] - 2022-08-01
|
||||||
|
|
||||||
|
@ -24,7 +24,8 @@ func InstrumentationScope(il instrumentation.Scope) *commonpb.InstrumentationSco
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return &commonpb.InstrumentationScope{
|
return &commonpb.InstrumentationScope{
|
||||||
Name: il.Name,
|
Name: il.Name,
|
||||||
Version: il.Version,
|
Version: il.Version,
|
||||||
|
Attributes: Iterator(il.Attributes.Iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright The OpenTelemetry Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package tracetransform // import "go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"go.opentelemetry.io/otel/attribute"
|
||||||
|
"go.opentelemetry.io/otel/sdk/instrumentation"
|
||||||
|
commonpb "go.opentelemetry.io/proto/otlp/common/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInstrumentationScope(t *testing.T) {
|
||||||
|
t.Run("Empty", func(t *testing.T) {
|
||||||
|
assert.Nil(t, InstrumentationScope(instrumentation.Scope{}))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Mapping", func(t *testing.T) {
|
||||||
|
var (
|
||||||
|
name = "instrumentation name"
|
||||||
|
version = "v0.1.0"
|
||||||
|
attr = attribute.NewSet(attribute.String("domain", "trace"))
|
||||||
|
attrPb = Iterator(attr.Iter())
|
||||||
|
)
|
||||||
|
expected := &commonpb.InstrumentationScope{
|
||||||
|
Name: name,
|
||||||
|
Version: version,
|
||||||
|
Attributes: attrPb,
|
||||||
|
}
|
||||||
|
actual := InstrumentationScope(instrumentation.Scope{
|
||||||
|
Name: name,
|
||||||
|
Version: version,
|
||||||
|
SchemaURL: "http://this.is.mapped.elsewhere.com",
|
||||||
|
Attributes: attr,
|
||||||
|
})
|
||||||
|
assert.Equal(t, expected, actual)
|
||||||
|
})
|
||||||
|
}
|
@ -186,7 +186,8 @@ func expectedJSON(now time.Time) string {
|
|||||||
"InstrumentationLibrary": {
|
"InstrumentationLibrary": {
|
||||||
"Name": "",
|
"Name": "",
|
||||||
"Version": "",
|
"Version": "",
|
||||||
"SchemaURL": ""
|
"SchemaURL": "",
|
||||||
|
"Attributes": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -14,7 +14,14 @@
|
|||||||
|
|
||||||
package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation"
|
package instrumentation // import "go.opentelemetry.io/otel/sdk/instrumentation"
|
||||||
|
|
||||||
// Scope represents the instrumentation scope.
|
import "go.opentelemetry.io/otel/attribute"
|
||||||
|
|
||||||
|
// Scope represents the instrumentation source of OpenTelemetry data.
|
||||||
|
//
|
||||||
|
// Code that uses OpenTelemetry APIs or data-models to produce telemetry needs
|
||||||
|
// to be identifiable by the receiver of that data. A Scope is used for this
|
||||||
|
// purpose, it uniquely identifies that code as the source and the extent to
|
||||||
|
// which it is relevant.
|
||||||
type Scope struct {
|
type Scope struct {
|
||||||
// Name is the name of the instrumentation scope. This should be the
|
// Name is the name of the instrumentation scope. This should be the
|
||||||
// Go package name of that scope.
|
// Go package name of that scope.
|
||||||
@ -23,4 +30,13 @@ type Scope struct {
|
|||||||
Version string
|
Version string
|
||||||
// SchemaURL of the telemetry emitted by the scope.
|
// SchemaURL of the telemetry emitted by the scope.
|
||||||
SchemaURL string
|
SchemaURL string
|
||||||
|
// Attributes describe the unique attributes of an instrumentation scope.
|
||||||
|
//
|
||||||
|
// These attributes are used to differentiate an instrumentation scope when
|
||||||
|
// it emits data that belong to different domains. For example, if both
|
||||||
|
// profiling data and client-side data are emitted as log records from the
|
||||||
|
// same instrumentation library, they may need to be differentiated by a
|
||||||
|
// telemetry receiver. In that case, these attributes are used to scope and
|
||||||
|
// differentiate the data.
|
||||||
|
Attributes attribute.Set
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,10 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
|
|||||||
name = defaultTracerName
|
name = defaultTracerName
|
||||||
}
|
}
|
||||||
is := instrumentation.Scope{
|
is := instrumentation.Scope{
|
||||||
Name: name,
|
Name: name,
|
||||||
Version: c.InstrumentationVersion(),
|
Version: c.InstrumentationVersion(),
|
||||||
SchemaURL: c.SchemaURL(),
|
SchemaURL: c.SchemaURL(),
|
||||||
|
Attributes: c.Attributes(),
|
||||||
}
|
}
|
||||||
t, ok := p.namedTracer[is]
|
t, ok := p.namedTracer[is]
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -153,7 +154,13 @@ func (p *TracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.T
|
|||||||
instrumentationScope: is,
|
instrumentationScope: is,
|
||||||
}
|
}
|
||||||
p.namedTracer[is] = t
|
p.namedTracer[is] = t
|
||||||
global.Info("Tracer created", "name", name, "version", c.InstrumentationVersion(), "schemaURL", c.SchemaURL())
|
global.Info(
|
||||||
|
"Tracer created",
|
||||||
|
"name", name,
|
||||||
|
"version", c.InstrumentationVersion(),
|
||||||
|
"schemaURL", c.SchemaURL(),
|
||||||
|
"attributes", c.Attributes(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
@ -911,6 +911,8 @@ func TestSetSpanStatusWithoutMessageWhenStatusIsNotError(t *testing.T) {
|
|||||||
func cmpDiff(x, y interface{}) string {
|
func cmpDiff(x, y interface{}) string {
|
||||||
return cmp.Diff(x, y,
|
return cmp.Diff(x, y,
|
||||||
cmp.AllowUnexported(snapshot{}),
|
cmp.AllowUnexported(snapshot{}),
|
||||||
|
cmp.AllowUnexported(attribute.Set{}),
|
||||||
|
cmp.AllowUnexported(attribute.Distinct{}),
|
||||||
cmp.AllowUnexported(attribute.Value{}),
|
cmp.AllowUnexported(attribute.Value{}),
|
||||||
cmp.AllowUnexported(Event{}),
|
cmp.AllowUnexported(Event{}),
|
||||||
cmp.AllowUnexported(trace.TraceState{}))
|
cmp.AllowUnexported(trace.TraceState{}))
|
||||||
|
@ -24,7 +24,8 @@ import (
|
|||||||
type TracerConfig struct {
|
type TracerConfig struct {
|
||||||
instrumentationVersion string
|
instrumentationVersion string
|
||||||
// Schema URL of the telemetry emitted by the Tracer.
|
// Schema URL of the telemetry emitted by the Tracer.
|
||||||
schemaURL string
|
schemaURL string
|
||||||
|
attributes attribute.Set
|
||||||
}
|
}
|
||||||
|
|
||||||
// InstrumentationVersion returns the version of the library providing instrumentation.
|
// InstrumentationVersion returns the version of the library providing instrumentation.
|
||||||
@ -37,6 +38,11 @@ func (t *TracerConfig) SchemaURL() string {
|
|||||||
return t.schemaURL
|
return t.schemaURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attributes returns the scope attribute set of the Tracer.
|
||||||
|
func (t *TracerConfig) Attributes() attribute.Set {
|
||||||
|
return t.attributes
|
||||||
|
}
|
||||||
|
|
||||||
// NewTracerConfig applies all the options to a returned TracerConfig.
|
// NewTracerConfig applies all the options to a returned TracerConfig.
|
||||||
func NewTracerConfig(options ...TracerOption) TracerConfig {
|
func NewTracerConfig(options ...TracerOption) TracerConfig {
|
||||||
var config TracerConfig
|
var config TracerConfig
|
||||||
@ -314,3 +320,13 @@ func WithSchemaURL(schemaURL string) TracerOption {
|
|||||||
return cfg
|
return cfg
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithScopeAttributes sets the attributes for the scope of a Tracer. The
|
||||||
|
// attributes are stored as an attribute set. Duplicate values are removed, the
|
||||||
|
// last value is used.
|
||||||
|
func WithScopeAttributes(attr ...attribute.KeyValue) TracerOption {
|
||||||
|
return tracerOptionFunc(func(cfg TracerConfig) TracerConfig {
|
||||||
|
cfg.attributes = attribute.NewSet(attr...)
|
||||||
|
return cfg
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -211,6 +211,7 @@ func TestTracerConfig(t *testing.T) {
|
|||||||
v1 := "semver:0.0.1"
|
v1 := "semver:0.0.1"
|
||||||
v2 := "semver:1.0.0"
|
v2 := "semver:1.0.0"
|
||||||
schemaURL := "https://opentelemetry.io/schemas/1.2.0"
|
schemaURL := "https://opentelemetry.io/schemas/1.2.0"
|
||||||
|
one, two := attribute.Int("key", 1), attribute.Int("key", 2)
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
options []TracerOption
|
options []TracerOption
|
||||||
expected TracerConfig
|
expected TracerConfig
|
||||||
@ -246,6 +247,24 @@ func TestTracerConfig(t *testing.T) {
|
|||||||
schemaURL: schemaURL,
|
schemaURL: schemaURL,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
[]TracerOption{
|
||||||
|
WithScopeAttributes(one, two),
|
||||||
|
},
|
||||||
|
TracerConfig{
|
||||||
|
attributes: attribute.NewSet(two),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]TracerOption{
|
||||||
|
WithScopeAttributes(two),
|
||||||
|
WithScopeAttributes(one),
|
||||||
|
},
|
||||||
|
TracerConfig{
|
||||||
|
attributes: attribute.NewSet(one),
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
config := NewTracerConfig(test.options...)
|
config := NewTracerConfig(test.options...)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user