diff --git a/sdk/metric/instrument.go b/sdk/metric/instrument.go index ab265c5e3df..8009540e6b2 100644 --- a/sdk/metric/instrument.go +++ b/sdk/metric/instrument.go @@ -85,34 +85,6 @@ type Instrument struct { nonComparable // nolint: unused } -// mask returns a copy of base with all non-zero-value fields of m replacing -// the fields of the returned copy. -func (base Instrument) mask(m Instrument) Instrument { - cp := base - if m.Name != "" { - cp.Name = m.Name - } - if m.Description != "" { - cp.Description = m.Description - } - if m.Kind != zeroInstrumentKind { - cp.Kind = m.Kind - } - if m.Unit != zeroUnit { - cp.Unit = m.Unit - } - if m.Scope.Name != "" { - cp.Scope.Name = m.Scope.Name - } - if m.Scope.Version != "" { - cp.Scope.Version = m.Scope.Version - } - if m.Scope.SchemaURL != "" { - cp.Scope.SchemaURL = m.Scope.SchemaURL - } - return cp -} - // empty returns if all fields of i are their zero-value. func (i Instrument) empty() bool { return i.Name == "" && @@ -167,8 +139,12 @@ func (i Instrument) matchesScope(other Instrument) bool { // Stream describes the stream of data an instrument produces. type Stream struct { - Instrument - + // Name is the human-readable identifier of the stream. + Name string + // Description describes the purpose of the data. + Description string + // Unit is the unit of measurement recorded. + Unit unit.Unit // Aggregation the stream uses for an instrument. Aggregation aggregation.Aggregation // AttributeFilter applied to all attributes recorded for an instrument. diff --git a/sdk/metric/view.go b/sdk/metric/view.go index 82eb7743af6..7f8da2d5892 100644 --- a/sdk/metric/view.go +++ b/sdk/metric/view.go @@ -48,11 +48,11 @@ type View func(Instrument) (Stream, bool) // all instrument names. // // The Stream mask only applies updates for non-zero-value fields. By default, -// the Instrument the View matches against will be use for the returned Stream -// and no Aggregation or AttributeFilter are set. If mask has a non-zero-value -// value for any of the Aggregation or AttributeFilter fields, or any of the -// Instrument fields, that value is used instead of the default. If you need to -// zero out an Stream field returned from a View, create a View directly. +// the Instrument the View matches against will be use for the Name, +// Description, and Unit of the returned Stream and no Aggregation or +// AttributeFilter are set. All non-zero-value value fields of mask are used +// instead of the default. If you need to zero out an Stream field returned +// from a View, create a View directly. func NewView(criteria Instrument, mask Stream) View { if criteria.empty() { return emptyView @@ -102,13 +102,23 @@ func NewView(criteria Instrument, mask Stream) View { return func(i Instrument) (Stream, bool) { if matchFunc(i) { - stream := Stream{ - Instrument: i.mask(mask.Instrument), + return Stream{ + Name: nonZero(mask.Name, i.Name), + Description: nonZero(mask.Description, i.Description), + Unit: nonZero(mask.Unit, i.Unit), Aggregation: agg, AttributeFilter: mask.AttributeFilter, - } - return stream, true + }, true } return Stream{}, false } } + +// nonZero returns v if it is non-zero-valued, otherwise alt. +func nonZero[T comparable](v, alt T) T { + var zero T + if v != zero { + return v + } + return alt +} diff --git a/sdk/metric/view_test.go b/sdk/metric/view_test.go index 9d075a8ffd6..082b0106ebd 100644 --- a/sdk/metric/view_test.go +++ b/sdk/metric/view_test.go @@ -350,88 +350,55 @@ func TestNewViewReplace(t *testing.T) { }{ { name: "Nothing", - want: func(ip Instrument) Stream { - return Stream{Instrument: ip} + want: func(i Instrument) Stream { + return Stream{ + Name: i.Name, + Description: i.Description, + Unit: i.Unit, + } }, }, { name: "Name", - mask: Stream{Instrument: Instrument{Name: alt}}, - want: func(ip Instrument) Stream { - ip.Name = alt - return Stream{Instrument: ip} + mask: Stream{Name: alt}, + want: func(i Instrument) Stream { + return Stream{ + Name: alt, + Description: i.Description, + Unit: i.Unit, + } }, }, { name: "Description", - mask: Stream{Instrument: Instrument{Description: alt}}, - want: func(ip Instrument) Stream { - ip.Description = alt - return Stream{Instrument: ip} - }, - }, - { - name: "Kind", - mask: Stream{Instrument: Instrument{ - Kind: InstrumentKindAsyncUpDownCounter, - }}, - want: func(ip Instrument) Stream { - ip.Kind = InstrumentKindAsyncUpDownCounter - return Stream{Instrument: ip} + mask: Stream{Description: alt}, + want: func(i Instrument) Stream { + return Stream{ + Name: i.Name, + Description: alt, + Unit: i.Unit, + } }, }, { name: "Unit", - mask: Stream{Instrument: Instrument{Unit: unit.Dimensionless}}, - want: func(ip Instrument) Stream { - ip.Unit = unit.Dimensionless - return Stream{Instrument: ip} - }, - }, - { - name: "ScopeName", - mask: Stream{Instrument: Instrument{Scope: scope(alt, "", "")}}, - want: func(ip Instrument) Stream { - ip.Scope.Name = alt - return Stream{Instrument: ip} - }, - }, - { - name: "ScopeVersion", - mask: Stream{Instrument: Instrument{Scope: scope("", alt, "")}}, - want: func(ip Instrument) Stream { - ip.Scope.Version = alt - return Stream{Instrument: ip} - }, - }, - { - name: "ScopeSchemaURL", - mask: Stream{Instrument: Instrument{Scope: scope("", "", alt)}}, - want: func(ip Instrument) Stream { - ip.Scope.SchemaURL = alt - return Stream{Instrument: ip} - }, - }, - { - name: "Scope", - mask: Stream{Instrument: Instrument{ - Scope: scope("Alt Scope Name", "1.1.1", "https://go.dev"), - }}, - want: func(ip Instrument) Stream { - ip.Scope.Name = "Alt Scope Name" - ip.Scope.Version = "1.1.1" - ip.Scope.SchemaURL = "https://go.dev" - return Stream{Instrument: ip} + mask: Stream{Unit: unit.Dimensionless}, + want: func(i Instrument) Stream { + return Stream{ + Name: i.Name, + Description: i.Description, + Unit: unit.Dimensionless, + } }, }, { name: "Aggregation", - mask: Stream{ - Aggregation: aggregation.LastValue{}, - }, - want: func(ip Instrument) Stream { + mask: Stream{Aggregation: aggregation.LastValue{}}, + want: func(i Instrument) Stream { return Stream{ - Instrument: ip, + Name: i.Name, + Description: i.Description, + Unit: i.Unit, Aggregation: aggregation.LastValue{}, } }, @@ -439,25 +406,16 @@ func TestNewViewReplace(t *testing.T) { { name: "Complete", mask: Stream{ - Instrument: Instrument{ - Name: alt, - Description: alt, - Kind: InstrumentKindAsyncUpDownCounter, - Unit: unit.Dimensionless, - Scope: scope(alt, alt, alt), - }, + Name: alt, + Description: alt, + Unit: unit.Dimensionless, Aggregation: aggregation.LastValue{}, }, - want: func(ip Instrument) Stream { - ip.Name = alt - ip.Description = alt - ip.Kind = InstrumentKindAsyncUpDownCounter - ip.Unit = unit.Dimensionless - ip.Scope.Name = alt - ip.Scope.Version = alt - ip.Scope.SchemaURL = alt + want: func(i Instrument) Stream { return Stream{ - Instrument: ip, + Name: alt, + Description: alt, + Unit: unit.Dimensionless, Aggregation: aggregation.LastValue{}, } },