1package metrics
2
3import (
4	"fmt"
5	"sync"
6
7	"go.opencensus.io/stats/view"
8)
9
10var registeredViews = map[string][]*view.View{}
11var mu = new(sync.Mutex)
12
13type ErrNamespace struct {
14	Namespace string
15}
16
17// ErrUnregisteredNamespace is an error for lookup of requested unregistered Namespace
18type ErrUnregisteredNamespace ErrNamespace
19
20func (e ErrUnregisteredNamespace) Error() string {
21	return fmt.Sprintf("no views found registered under Namespace %s", e.Namespace)
22}
23
24// ErrDuplicateNamespaceRegistration is an error for a Namespace that has already
25// registered views
26type ErrDuplicateNamespaceRegistration ErrNamespace
27
28func (e ErrDuplicateNamespaceRegistration) Error() string {
29	return fmt.Sprintf("duplicate registration of views by Namespace %s", e.Namespace)
30}
31
32// RegisterViews accepts a namespace and a slice of Views, which will be registered
33// with opencensus and maintained in the global registered views map
34func RegisterViews(namespace string, views ...*view.View) error {
35	mu.Lock()
36	defer mu.Unlock()
37	_, ok := registeredViews[namespace]
38	if ok {
39		return ErrDuplicateNamespaceRegistration{Namespace: namespace}
40	} else {
41		registeredViews[namespace] = views
42	}
43
44	return nil
45}
46
47// LookupViews returns all views for a Namespace name. Returns an error if the
48// Namespace has not been registered.
49func LookupViews(name string) ([]*view.View, error) {
50	mu.Lock()
51	defer mu.Unlock()
52	views, ok := registeredViews[name]
53	if !ok {
54		return nil, ErrUnregisteredNamespace{Namespace: name}
55	}
56	response := make([]*view.View, len(views))
57	copy(response, views)
58	return response, nil
59}
60
61// AllViews returns all registered views as a single slice
62func AllViews() []*view.View {
63	var views []*view.View
64	mu.Lock()
65	defer mu.Unlock()
66	for _, vs := range registeredViews {
67		views = append(views, vs...)
68	}
69	return views
70}
71