-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from libp2p/feat/metrics-redux
Add OpenCensus metrics registration functionality to core
- Loading branch information
Showing
2 changed files
with
164 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package metrics | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"go.opencensus.io/stats/view" | ||
) | ||
|
||
var registeredViews = map[string][]*view.View{} | ||
var mu = new(sync.Mutex) | ||
|
||
type ErrNamespace struct { | ||
Namespace string | ||
} | ||
|
||
// ErrUnregisteredNamespace is an error for lookup of requested unregistered Namespace | ||
type ErrUnregisteredNamespace ErrNamespace | ||
|
||
func (e ErrUnregisteredNamespace) Error() string { | ||
return fmt.Sprintf("no views found registered under Namespace %s", e.Namespace) | ||
} | ||
|
||
// ErrDuplicateNamespaceRegistration is an error for a Namespace that has already | ||
// registered views | ||
type ErrDuplicateNamespaceRegistration ErrNamespace | ||
|
||
func (e ErrDuplicateNamespaceRegistration) Error() string { | ||
return fmt.Sprintf("duplicate registration of views by Namespace %s", e.Namespace) | ||
} | ||
|
||
// RegisterViews accepts a namespace and a slice of Views, which will be registered | ||
// with opencensus and maintained in the global registered views map | ||
func RegisterViews(namespace string, views ...*view.View) error { | ||
mu.Lock() | ||
defer mu.Unlock() | ||
_, ok := registeredViews[namespace] | ||
if ok { | ||
return ErrDuplicateNamespaceRegistration{Namespace: namespace} | ||
} else { | ||
registeredViews[namespace] = views | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// LookupViews returns all views for a Namespace name. Returns an error if the | ||
// Namespace has not been registered. | ||
func LookupViews(name string) ([]*view.View, error) { | ||
mu.Lock() | ||
defer mu.Unlock() | ||
views, ok := registeredViews[name] | ||
if !ok { | ||
return nil, ErrUnregisteredNamespace{Namespace: name} | ||
} | ||
response := make([]*view.View, len(views)) | ||
copy(response, views) | ||
return response, nil | ||
} | ||
|
||
// AllViews returns all registered views as a single slice | ||
func AllViews() []*view.View { | ||
var views []*view.View | ||
mu.Lock() | ||
defer mu.Unlock() | ||
for _, vs := range registeredViews { | ||
views = append(views, vs...) | ||
} | ||
return views | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package metrics | ||
|
||
import ( | ||
"fmt" | ||
"go.opencensus.io/stats" | ||
"testing" | ||
|
||
"go.opencensus.io/stats/view" | ||
) | ||
|
||
func newTestMeasure(name string) stats.Measure { | ||
return stats.Int64(fmt.Sprintf("test/measure/%s", name), | ||
fmt.Sprintf("Test measurement %s", name), | ||
stats.UnitDimensionless, | ||
) | ||
} | ||
|
||
func newTestView(name string) *view.View { | ||
return &view.View{ | ||
Name: fmt.Sprintf("test/%s", name), | ||
Description: fmt.Sprintf("Test view %s", name), | ||
Measure: newTestMeasure(name), | ||
Aggregation: view.LastValue(), | ||
} | ||
} | ||
|
||
func TestRegisteringViews(t *testing.T) { | ||
registeredViews = make(map[string][]*view.View) | ||
|
||
t.Run("test registering first views", func(t *testing.T) { | ||
testView := newTestView("empty-map-0") | ||
|
||
if err := RegisterViews("test", testView); err != nil { | ||
t.Fatal("unable to register view in empty map", err) | ||
} | ||
}) | ||
|
||
t.Run("test registering with existing views", func(t *testing.T) { | ||
testView := newTestView("empty-map-1") | ||
testView2 := newTestView("existing-entity-0") | ||
|
||
if err := RegisterViews("test2", testView); err != nil { | ||
t.Fatal("unable to register view in empty map", err) | ||
} | ||
if err := RegisterViews("test3", testView2); err != nil { | ||
t.Fatal("unable to register view in map", err) | ||
} | ||
}) | ||
|
||
t.Run("test registering duplicate views", func(t *testing.T) { | ||
testView := newTestView("empty-map-2") | ||
testView2 := newTestView("existing-entity-1") | ||
|
||
if err := RegisterViews("test4", testView); err != nil { | ||
t.Fatal("unable to register view in empty map", err) | ||
} | ||
if err := RegisterViews("test4", testView2); err == nil { | ||
t.Fatal("allowed duplicate view registration") | ||
} | ||
}) | ||
|
||
t.Run("test looking up views", func(t *testing.T) { | ||
testView := newTestView("empty-map-3") | ||
|
||
if err := RegisterViews("test5", testView); err != nil { | ||
t.Fatal("unable to register view in empty map", err) | ||
} | ||
|
||
views, err := LookupViews("test5") | ||
if err != nil { | ||
t.Fatal("error looking up views", err) | ||
} | ||
|
||
if views[0].Name != testView.Name { | ||
t.Fatal("incorrect view lookup, received name:", views[0].Name) | ||
} | ||
}) | ||
} | ||
|
||
func TestAllViews(t *testing.T) { | ||
registeredViews = make(map[string][]*view.View) | ||
t.Run("test retrieving all views", func(t *testing.T) { | ||
views := []*view.View{newTestView("all-views-0"), newTestView("all-views-1"), newTestView("all-views-2")} | ||
|
||
if err := RegisterViews("test6", views...); err != nil { | ||
t.Fatal("unable to register multiple views at once", err) | ||
} | ||
|
||
allViews := AllViews() | ||
if len(allViews) != len(views) { | ||
t.Fatalf("didn't receive equal number of views: %d %d", len(views), len(allViews)) | ||
} | ||
}) | ||
} |