instrument.go 9.4 KB

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