instrument.go (9513B)
1 // Copyright The OpenTelemetry Authors 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 metric // import "go.opentelemetry.io/otel/metric" 16 17 import "go.opentelemetry.io/otel/attribute" 18 19 // Observable is used as a grouping mechanism for all instruments that are 20 // updated within a Callback. 21 type Observable interface { 22 observable() 23 } 24 25 // InstrumentOption applies options to all instruments. 26 type InstrumentOption interface { 27 Int64CounterOption 28 Int64UpDownCounterOption 29 Int64HistogramOption 30 Int64ObservableCounterOption 31 Int64ObservableUpDownCounterOption 32 Int64ObservableGaugeOption 33 34 Float64CounterOption 35 Float64UpDownCounterOption 36 Float64HistogramOption 37 Float64ObservableCounterOption 38 Float64ObservableUpDownCounterOption 39 Float64ObservableGaugeOption 40 } 41 42 type descOpt string 43 44 func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { 45 c.description = string(o) 46 return c 47 } 48 49 func (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { 50 c.description = string(o) 51 return c 52 } 53 54 func (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { 55 c.description = string(o) 56 return c 57 } 58 59 func (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { 60 c.description = string(o) 61 return c 62 } 63 64 func (o descOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig { 65 c.description = string(o) 66 return c 67 } 68 69 func (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { 70 c.description = string(o) 71 return c 72 } 73 74 func (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { 75 c.description = string(o) 76 return c 77 } 78 79 func (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { 80 c.description = string(o) 81 return c 82 } 83 84 func (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { 85 c.description = string(o) 86 return c 87 } 88 89 func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { 90 c.description = string(o) 91 return c 92 } 93 94 func (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig { 95 c.description = string(o) 96 return c 97 } 98 99 func (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { 100 c.description = string(o) 101 return c 102 } 103 104 // WithDescription sets the instrument description. 105 func WithDescription(desc string) InstrumentOption { return descOpt(desc) } 106 107 type unitOpt string 108 109 func (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { 110 c.unit = string(o) 111 return c 112 } 113 114 func (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { 115 c.unit = string(o) 116 return c 117 } 118 119 func (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { 120 c.unit = string(o) 121 return c 122 } 123 124 func (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { 125 c.unit = string(o) 126 return c 127 } 128 129 func (o unitOpt) applyFloat64ObservableUpDownCounter(c Float64ObservableUpDownCounterConfig) Float64ObservableUpDownCounterConfig { 130 c.unit = string(o) 131 return c 132 } 133 134 func (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { 135 c.unit = string(o) 136 return c 137 } 138 139 func (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { 140 c.unit = string(o) 141 return c 142 } 143 144 func (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { 145 c.unit = string(o) 146 return c 147 } 148 149 func (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { 150 c.unit = string(o) 151 return c 152 } 153 154 func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { 155 c.unit = string(o) 156 return c 157 } 158 159 func (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig { 160 c.unit = string(o) 161 return c 162 } 163 164 func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { 165 c.unit = string(o) 166 return c 167 } 168 169 // WithUnit sets the instrument unit. 170 func WithUnit(u string) InstrumentOption { return unitOpt(u) } 171 172 // AddOption applies options to an addition measurement. See 173 // [MeasurementOption] for other options that can be used as an AddOption. 174 type AddOption interface { 175 applyAdd(AddConfig) AddConfig 176 } 177 178 // AddConfig contains options for an addition measurement. 179 type AddConfig struct { 180 attrs attribute.Set 181 } 182 183 // NewAddConfig returns a new [AddConfig] with all opts applied. 184 func NewAddConfig(opts []AddOption) AddConfig { 185 config := AddConfig{attrs: *attribute.EmptySet()} 186 for _, o := range opts { 187 config = o.applyAdd(config) 188 } 189 return config 190 } 191 192 // Attributes returns the configured attribute set. 193 func (c AddConfig) Attributes() attribute.Set { 194 return c.attrs 195 } 196 197 // RecordOption applies options to an addition measurement. See 198 // [MeasurementOption] for other options that can be used as a RecordOption. 199 type RecordOption interface { 200 applyRecord(RecordConfig) RecordConfig 201 } 202 203 // RecordConfig contains options for a recorded measurement. 204 type RecordConfig struct { 205 attrs attribute.Set 206 } 207 208 // NewRecordConfig returns a new [RecordConfig] with all opts applied. 209 func NewRecordConfig(opts []RecordOption) RecordConfig { 210 config := RecordConfig{attrs: *attribute.EmptySet()} 211 for _, o := range opts { 212 config = o.applyRecord(config) 213 } 214 return config 215 } 216 217 // Attributes returns the configured attribute set. 218 func (c RecordConfig) Attributes() attribute.Set { 219 return c.attrs 220 } 221 222 // ObserveOption applies options to an addition measurement. See 223 // [MeasurementOption] for other options that can be used as a ObserveOption. 224 type ObserveOption interface { 225 applyObserve(ObserveConfig) ObserveConfig 226 } 227 228 // ObserveConfig contains options for an observed measurement. 229 type ObserveConfig struct { 230 attrs attribute.Set 231 } 232 233 // NewObserveConfig returns a new [ObserveConfig] with all opts applied. 234 func NewObserveConfig(opts []ObserveOption) ObserveConfig { 235 config := ObserveConfig{attrs: *attribute.EmptySet()} 236 for _, o := range opts { 237 config = o.applyObserve(config) 238 } 239 return config 240 } 241 242 // Attributes returns the configured attribute set. 243 func (c ObserveConfig) Attributes() attribute.Set { 244 return c.attrs 245 } 246 247 // MeasurementOption applies options to all instrument measurement. 248 type MeasurementOption interface { 249 AddOption 250 RecordOption 251 ObserveOption 252 } 253 254 type attrOpt struct { 255 set attribute.Set 256 } 257 258 // mergeSets returns the union of keys between a and b. Any duplicate keys will 259 // use the value associated with b. 260 func mergeSets(a, b attribute.Set) attribute.Set { 261 // NewMergeIterator uses the first value for any duplicates. 262 iter := attribute.NewMergeIterator(&b, &a) 263 merged := make([]attribute.KeyValue, 0, a.Len()+b.Len()) 264 for iter.Next() { 265 merged = append(merged, iter.Attribute()) 266 } 267 return attribute.NewSet(merged...) 268 } 269 270 func (o attrOpt) applyAdd(c AddConfig) AddConfig { 271 switch { 272 case o.set.Len() == 0: 273 case c.attrs.Len() == 0: 274 c.attrs = o.set 275 default: 276 c.attrs = mergeSets(c.attrs, o.set) 277 } 278 return c 279 } 280 281 func (o attrOpt) applyRecord(c RecordConfig) RecordConfig { 282 switch { 283 case o.set.Len() == 0: 284 case c.attrs.Len() == 0: 285 c.attrs = o.set 286 default: 287 c.attrs = mergeSets(c.attrs, o.set) 288 } 289 return c 290 } 291 292 func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig { 293 switch { 294 case o.set.Len() == 0: 295 case c.attrs.Len() == 0: 296 c.attrs = o.set 297 default: 298 c.attrs = mergeSets(c.attrs, o.set) 299 } 300 return c 301 } 302 303 // WithAttributeSet sets the attribute Set associated with a measurement is 304 // made with. 305 // 306 // If multiple WithAttributeSet or WithAttributes options are passed the 307 // attributes will be merged together in the order they are passed. Attributes 308 // with duplicate keys will use the last value passed. 309 func WithAttributeSet(attributes attribute.Set) MeasurementOption { 310 return attrOpt{set: attributes} 311 } 312 313 // WithAttributes converts attributes into an attribute Set and sets the Set to 314 // be associated with a measurement. This is shorthand for: 315 // 316 // cp := make([]attribute.KeyValue, len(attributes)) 317 // copy(cp, attributes) 318 // WithAttributes(attribute.NewSet(cp...)) 319 // 320 // [attribute.NewSet] may modify the passed attributes so this will make a copy 321 // of attributes before creating a set in order to ensure this function is 322 // concurrent safe. This makes this option function less optimized in 323 // comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be 324 // preferred for performance sensitive code. 325 // 326 // See [WithAttributeSet] for information about how multiple WithAttributes are 327 // merged. 328 func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption { 329 cp := make([]attribute.KeyValue, len(attributes)) 330 copy(cp, attributes) 331 return attrOpt{set: attribute.NewSet(cp...)} 332 }