github.com/mhutchinson/trillian@v1.2.1/monitoring/inert.go (about) 1 // Copyright 2017 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package monitoring 16 17 import ( 18 "fmt" 19 "strings" 20 "sync" 21 22 "github.com/golang/glog" 23 ) 24 25 // InertMetricFactory creates inert metrics for testing. 26 type InertMetricFactory struct{} 27 28 // NewCounter creates a new inert Counter. 29 func (imf InertMetricFactory) NewCounter(name, help string, labelNames ...string) Counter { 30 return &InertFloat{ 31 labelCount: len(labelNames), 32 vals: make(map[string]float64), 33 } 34 } 35 36 // NewGauge creates a new inert Gauge. 37 func (imf InertMetricFactory) NewGauge(name, help string, labelNames ...string) Gauge { 38 return &InertFloat{ 39 labelCount: len(labelNames), 40 vals: make(map[string]float64), 41 } 42 } 43 44 // NewHistogram creates a new inert Histogram. 45 func (imf InertMetricFactory) NewHistogram(name, help string, labelNames ...string) Histogram { 46 return &InertDistribution{ 47 labelCount: len(labelNames), 48 counts: make(map[string]uint64), 49 sums: make(map[string]float64), 50 } 51 } 52 53 // InertFloat is an internal-only implementation of both the Counter and Gauge interfaces. 54 type InertFloat struct { 55 labelCount int 56 mu sync.Mutex 57 vals map[string]float64 58 } 59 60 // Inc adds 1 to the value. 61 func (m *InertFloat) Inc(labelVals ...string) { 62 m.Add(1.0, labelVals...) 63 } 64 65 // Dec subtracts 1 from the value. 66 func (m *InertFloat) Dec(labelVals ...string) { 67 m.Add(-1.0, labelVals...) 68 } 69 70 // Add adds the given amount to the value. 71 func (m *InertFloat) Add(val float64, labelVals ...string) { 72 m.mu.Lock() 73 defer m.mu.Unlock() 74 key, err := keyForLabels(labelVals, m.labelCount) 75 if err != nil { 76 glog.Error(err.Error()) 77 return 78 } 79 m.vals[key] += val 80 } 81 82 // Set sets the value. 83 func (m *InertFloat) Set(val float64, labelVals ...string) { 84 m.mu.Lock() 85 defer m.mu.Unlock() 86 key, err := keyForLabels(labelVals, m.labelCount) 87 if err != nil { 88 glog.Error(err.Error()) 89 return 90 } 91 m.vals[key] = val 92 } 93 94 // Value returns the current value. 95 func (m *InertFloat) Value(labelVals ...string) float64 { 96 m.mu.Lock() 97 defer m.mu.Unlock() 98 key, err := keyForLabels(labelVals, m.labelCount) 99 if err != nil { 100 glog.Error(err.Error()) 101 return 0.0 102 } 103 return m.vals[key] 104 } 105 106 // InertDistribution is an internal-only implementation of the Distribution interface. 107 type InertDistribution struct { 108 labelCount int 109 mu sync.Mutex 110 counts map[string]uint64 111 sums map[string]float64 112 } 113 114 // Observe adds a single observation to the distribution. 115 func (m *InertDistribution) Observe(val float64, labelVals ...string) { 116 m.mu.Lock() 117 defer m.mu.Unlock() 118 key, err := keyForLabels(labelVals, m.labelCount) 119 if err != nil { 120 glog.Error(err.Error()) 121 return 122 } 123 m.counts[key]++ 124 m.sums[key] += val 125 } 126 127 // Info returns count, sum for the distribution. 128 func (m *InertDistribution) Info(labelVals ...string) (uint64, float64) { 129 m.mu.Lock() 130 defer m.mu.Unlock() 131 key, err := keyForLabels(labelVals, m.labelCount) 132 if err != nil { 133 glog.Error(err.Error()) 134 return 0, 0.0 135 } 136 return m.counts[key], m.sums[key] 137 } 138 139 func keyForLabels(labelVals []string, count int) (string, error) { 140 if len(labelVals) != count { 141 return "", fmt.Errorf("invalid label count %d; want %d", len(labelVals), count) 142 } 143 return strings.Join(labelVals, "|"), nil 144 }