1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00
moby--moby/vendor/github.com/docker/swarmkit/manager/metrics/collector.go
Aaron Lehmann 721b7a7fad Vendor swarmkit ae29cf2
Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
2017-05-12 17:36:11 -07:00

104 lines
2.3 KiB
Go

package metrics
import (
"context"
"strings"
metrics "github.com/docker/go-metrics"
"github.com/docker/swarmkit/api"
"github.com/docker/swarmkit/manager/state/store"
)
var (
ns = metrics.NewNamespace("swarm", "manager", nil)
nodesMetric metrics.LabeledGauge
)
func init() {
nodesMetric = ns.NewLabeledGauge("nodes", "The number of nodes", "", "state")
for _, state := range api.NodeStatus_State_name {
nodesMetric.WithValues(strings.ToLower(state)).Set(0)
}
metrics.Register(ns)
}
// Collector collects swarmkit metrics
type Collector struct {
store *store.MemoryStore
// stopChan signals to the state machine to stop running.
stopChan chan struct{}
// doneChan is closed when the state machine terminates.
doneChan chan struct{}
}
// NewCollector creates a new metrics collector
func NewCollector(store *store.MemoryStore) *Collector {
return &Collector{
store: store,
stopChan: make(chan struct{}),
doneChan: make(chan struct{}),
}
}
func (c *Collector) updateNodeState(prevNode, newNode *api.Node) {
// Skip updates if nothing changed.
if prevNode != nil && newNode != nil && prevNode.Status.State == newNode.Status.State {
return
}
if prevNode != nil {
nodesMetric.WithValues(strings.ToLower(prevNode.Status.State.String())).Dec(1)
}
if newNode != nil {
nodesMetric.WithValues(strings.ToLower(newNode.Status.State.String())).Inc(1)
}
}
// Run contains the collector event loop
func (c *Collector) Run(ctx context.Context) error {
defer close(c.doneChan)
watcher, cancel, err := store.ViewAndWatch(c.store, func(readTx store.ReadTx) error {
nodes, err := store.FindNodes(readTx, store.All)
if err != nil {
return err
}
for _, node := range nodes {
c.updateNodeState(nil, node)
}
return nil
})
if err != nil {
return err
}
defer cancel()
for {
select {
case event := <-watcher:
switch v := event.(type) {
case api.EventCreateNode:
c.updateNodeState(nil, v.Node)
case api.EventUpdateNode:
c.updateNodeState(v.OldNode, v.Node)
case api.EventDeleteNode:
c.updateNodeState(v.Node, nil)
}
case <-c.stopChan:
return nil
}
}
}
// Stop stops the collector.
func (c *Collector) Stop() {
close(c.stopChan)
<-c.doneChan
// Clean the metrics on exit.
for _, state := range api.NodeStatus_State_name {
nodesMetric.WithValues(strings.ToLower(state)).Set(0)
}
}