mirror of https://github.com/libp2p/go-libp2p.git
Cole Brown
5 years ago
2 changed files with 164 additions and 0 deletions
@ -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 |
||||
|
} |
@ -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)) |
||||
|
} |
||||
|
}) |
||||
|
} |
Loading…
Reference in new issue