github.com/puellanivis/breton@v0.2.16/lib/metrics/option.go (about) 1 package metrics 2 3 import ( 4 "time" 5 6 "github.com/prometheus/client_golang/prometheus" 7 ) 8 9 // An Option defines specific optional feature for a Metric. When applied, 10 // it returns a new Option that will revert the feature to the previous state. 11 type Option func(m *metric) Option 12 13 // withLabelScope allows for toggling labelScopes directly, and not just 14 // a list of Labelers to keep enscoping into. 15 func withLabelScope(labels *labelScope) Option { 16 return func(m *metric) Option { 17 save := m.labels 18 19 m.labels = labels 20 21 return withLabelScope(save) 22 } 23 } 24 25 // WithLabels defines a set of Labels to use for a Metric. 26 // * Label: a Label with the given name, no default. 27 // * Label.WithValue: a Label with the given name, and default value. 28 // * Label.Const; a Label with the given name, and a constant value. 29 func WithLabels(labels ...Labeler) Option { 30 return func(m *metric) Option { 31 save := m.labels 32 33 if save == nil { 34 m.labels = defineLabels(labels...) 35 36 } else { 37 m.labels = m.labels.With(labels...) 38 } 39 40 return withLabelScope(save) 41 } 42 } 43 44 // WithRegistry defines the Registry to which a Metric will be registered. 45 // By default, every Metric will be registered with the default prometheus.Registery. 46 func WithRegistry(registry *prometheus.Registry) Option { 47 return func(m *metric) Option { 48 save := m.registry 49 50 m.registry = registry 51 52 return WithRegistry(save) 53 } 54 } 55 56 // LinearBuckets defines a series of linear buckets defined by: 57 // 58 // for i from 0 to count: a_i = start + width × i 59 // 60 // (Caller MUST NOT pass a count <= 0) 61 func LinearBuckets(start, width float64, count uint) Option { 62 return WithBuckets(prometheus.LinearBuckets(start, width, int(count))...) 63 } 64 65 // ExponentialBuckets defines a series of exponential buckets defined by: 66 // 67 // for i from 0 to count: a_i = start × factor^i 68 // 69 // (Caller MUST NOT pass a count <= 0, start <= 0, or factor <= 1) 70 func ExponentialBuckets(start, factor float64, count uint) Option { 71 return WithBuckets(prometheus.ExponentialBuckets(start, factor, int(count))...) 72 } 73 74 // WithBuckets defines the buckets into which observations are counted. Each 75 // element in the slice is the upper inclusive bound of a bucket. 76 // 77 // (Caller MUST ensure that the buckets are defined in increasing order.) 78 // 79 // (Caller MUST not include the highest +Inf bucket boundary, it is added 80 // implicity.) 81 func WithBuckets(buckets ...float64) Option { 82 return func(m *metric) Option { 83 if m.histogramSettings == nil { 84 panic("metric is not a histogram") 85 } 86 87 save := m.histogramSettings.buckets 88 89 m.histogramSettings.buckets = buckets 90 91 return WithBuckets(save...) 92 } 93 94 } 95 96 // WithObjectives defines the quantile rank estimates with their respective 97 // absolute error. If Objectives[q] = e, then the value reported for q will be 98 // the φ-quantile value for some φ in the range q±e. 99 // The default is to have no Objectives. 100 // For a common case of 50-90-99th percentiles, use CommonObjectives 101 func WithObjectives(objectives map[float64]float64) Option { 102 return func(m *metric) Option { 103 if m.summarySettings == nil { 104 panic("metric is not a summary") 105 } 106 107 save := m.objectives 108 109 m.objectives = objectives 110 111 return WithObjectives(save) 112 } 113 } 114 115 var ( 116 commonObjectives = map[float64]float64{ 117 0.5: 0.05, 118 0.9: 0.01, 119 0.99: 0.001, 120 } 121 ) 122 123 // CommonObjectives defines a common set of Objectives, which track the 124 // percentiles: 50±5 (the median), 90±1, and 99±0.1 125 // By default, a Summary will not have any Objectives. 126 func CommonObjectives() Option { 127 return WithObjectives(commonObjectives) 128 } 129 130 // WithMaxAge defines the duration for which an observation stays relevant 131 // for the summary. Must be positive. 132 func WithMaxAge(value time.Duration) Option { 133 if value <= 0 { 134 panic("value for maximum age must be positive") 135 } 136 137 return func(m *metric) Option { 138 if m.summarySettings == nil { 139 panic("metric is not a summary") 140 } 141 142 save := m.summarySettings.maxAge 143 144 m.summarySettings.maxAge = value 145 146 return WithMaxAge(save) 147 } 148 } 149 150 // WithAgeBuckets is the number of buckets used to exclude observations that 151 // are older than MaxAge from the summary. A higher number has a resource 152 // penalty, so only increase it if the higher resolution is really required. 153 // For very high observation rates, you might want to reduce the number of 154 // age buckets. With only one age bucket, you will effectively see a complete 155 // reset of the summary each time MaxAge has passed. 156 func WithAgeBuckets(value uint32) Option { 157 return func(m *metric) Option { 158 if m.summarySettings == nil { 159 panic("metric is not a summary") 160 } 161 162 save := m.summarySettings.ageBuckets 163 164 m.summarySettings.ageBuckets = value 165 166 return WithAgeBuckets(save) 167 } 168 } 169 170 // WithBufCap deifnes the default sample stream buffer size. The default value 171 // should suffice for most users. If there is a need to increase the value, 172 // a multiple of 500 is recommended (because that is the internal buffer size 173 // of the underlying package "github.com/bmizerany/perks/quantile") 174 // 175 // This Option exposes implementation details, which is undesirable. 176 func WithBufCap(value uint32) Option { 177 return func(m *metric) Option { 178 if m.summarySettings == nil { 179 panic("metric is not a summary") 180 } 181 182 save := m.summarySettings.bufCap 183 184 m.summarySettings.bufCap = value 185 186 return WithBufCap(save) 187 } 188 }