Skip to content

Commit

Permalink
Add view example tests (#3460)
Browse files Browse the repository at this point in the history
* Add the InstrumentKind type and vars to sdk/metric

* Add the Instrument type to sdk/metric

* Add the Stream type to sdk/metric

* Add the View type to sdk/metric

* Add NewView to create Views matching OTel spec

* Add unit tests for NewView

* Add changes to changelog

* Apply suggestions from code review

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>

* Update CHANGELOG.md

* Update match and mask comments of Instrument

* Explain wildcard logic in NewView with comment

* Drop views that replace name for multi-inst match

* Comment how users are expected to match zero-vals

* Remove InstrumentKind and Scope from Stream

* Fix redundant word in NewView comment

* Add view example tests

* Update comments to examples

* Fix broken English

Co-authored-by: Anthony Mirabella <a9@aneurysm9.com>
  • Loading branch information
MrAlias and Aneurysm9 committed Nov 21, 2022
1 parent 0847081 commit dbf960c
Showing 1 changed file with 133 additions and 0 deletions.
133 changes: 133 additions & 0 deletions sdk/metric/view_test.go
Expand Up @@ -15,6 +15,8 @@
package metric // import "go.opentelemetry.io/otel/sdk/metric"

import (
"fmt"
"regexp"
"testing"

"github.com/go-logr/logr"
Expand Down Expand Up @@ -469,3 +471,134 @@ func TestNewViewAggregationErrorLogged(t *testing.T) {
assert.Nil(t, got.Aggregation, "erroring aggregation used")
assert.Equal(t, 1, l.ErrorN())
}

func ExampleNewView() {
// Create a view that renames the "latency" instrument from the v0.34.0
// version of the "http" instrumentation library as "request.latency".
view := NewView(Instrument{
Name: "latency",
Scope: instrumentation.Scope{
Name: "http",
Version: "v0.34.0",
},
}, Stream{Name: "request.latency"})

// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option. Below is an example of how the view will
// function in the SDK for certain instruments.

stream, _ := view(Instrument{
Name: "latency",
Description: "request latency",
Unit: unit.Milliseconds,
Kind: InstrumentKindSyncCounter,
Scope: instrumentation.Scope{
Name: "http",
Version: "v0.34.0",
SchemaURL: "https://opentelemetry.io/schemas/1.0.0",
},
})
fmt.Println("name:", stream.Name)
fmt.Println("description:", stream.Description)
fmt.Println("unit:", stream.Unit)
// Output:
// name: request.latency
// description: request latency
// unit: ms
}

func ExampleNewView_drop() {
// Create a view that sets the drop aggregator for all instrumentation from
// the "db" library, effectively turning-off all instrumentation from that
// library.
view := NewView(
Instrument{Scope: instrumentation.Scope{Name: "db"}},
Stream{Aggregation: aggregation.Drop{}},
)

// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option. Below is an example of how the view will
// function in the SDK for certain instruments.

stream, _ := view(Instrument{
Name: "queries",
Kind: InstrumentKindSyncCounter,
Scope: instrumentation.Scope{Name: "db", Version: "v0.4.0"},
})
fmt.Println("name:", stream.Name)
fmt.Printf("aggregation: %#v", stream.Aggregation)
// Output:
// name: queries
// aggregation: aggregation.Drop{}
}

func ExampleNewView_wildcard() {
// Create a view that sets unit to milliseconds for any instrument with a
// name suffix of ".ms".
view := NewView(
Instrument{Name: "*.ms"},
Stream{Unit: unit.Milliseconds},
)

// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option. Below is an example of how the view
// function in the SDK for certain instruments.

stream, _ := view(Instrument{
Name: "computation.time.ms",
Unit: unit.Dimensionless,
})
fmt.Println("name:", stream.Name)
fmt.Println("unit:", stream.Unit)
// Output:
// name: computation.time.ms
// unit: ms
}

func ExampleView() {
// The NewView function provides convenient creation of common Views
// construction. However, it is limited in what it can create.
//
// When NewView is not able to provide the functionally needed, a custom
// View can be constructed directly. Here a custom View is constructed that
// uses Go's regular expression matching to ensure all data stream names
// have a suffix of the units it uses.

re := regexp.MustCompile(`[._](ms|byte)$`)
var view View = func(i Instrument) (Stream, bool) {
s := Stream{Name: i.Name, Description: i.Description, Unit: i.Unit}
// Any instrument that does not have a unit suffix defined, but has a
// dimensional unit defined, update the name with a unit suffix.
if re.MatchString(i.Name) {
return s, false
}
switch i.Unit {
case unit.Milliseconds:
s.Name += ".ms"
case unit.Bytes:
s.Name += ".byte"
default:
return s, false
}
return s, true
}

// The created view can then be registered with the OpenTelemetry metric
// SDK using the WithView option. Below is an example of how the view will
// function in the SDK for certain instruments.

stream, _ := view(Instrument{
Name: "computation.time.ms",
Unit: unit.Milliseconds,
})
fmt.Println("name:", stream.Name)

stream, _ = view(Instrument{
Name: "heap.size",
Unit: unit.Bytes,
})
fmt.Println("name:", stream.Name)
// Output:
// name: computation.time.ms
// name: heap.size.byte
}

0 comments on commit dbf960c

Please sign in to comment.