mirror of https://github.com/libp2p/go-libp2p.git
bigs
5 years ago
committed by
GitHub
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