| // Copyright The OpenTelemetry Authors |
| // SPDX-License-Identifier: Apache-2.0 |
| |
| package metric // import "go.opentelemetry.io/otel/metric" |
| |
| import "go.opentelemetry.io/otel/attribute" |
| |
| // Observable is used as a grouping mechanism for all instruments that are |
| // updated within a Callback. |
| type Observable interface { |
| observable() |
| } |
| |
| // InstrumentOption applies options to all instruments. |
| type InstrumentOption interface { |
| Int64CounterOption |
| Int64UpDownCounterOption |
| Int64HistogramOption |
| Int64GaugeOption |
| Int64ObservableCounterOption |
| Int64ObservableUpDownCounterOption |
| Int64ObservableGaugeOption |
| |
| Float64CounterOption |
| Float64UpDownCounterOption |
| Float64HistogramOption |
| Float64GaugeOption |
| Float64ObservableCounterOption |
| Float64ObservableUpDownCounterOption |
| Float64ObservableGaugeOption |
| } |
| |
| // HistogramOption applies options to histogram instruments. |
| type HistogramOption interface { |
| Int64HistogramOption |
| Float64HistogramOption |
| } |
| |
| type descOpt string |
| |
| func (o descOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64ObservableUpDownCounter( |
| c Float64ObservableUpDownCounterConfig, |
| ) Float64ObservableUpDownCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64ObservableUpDownCounter( |
| c Int64ObservableUpDownCounterConfig, |
| ) Int64ObservableUpDownCounterConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| func (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { |
| c.description = string(o) |
| return c |
| } |
| |
| // WithDescription sets the instrument description. |
| func WithDescription(desc string) InstrumentOption { return descOpt(desc) } |
| |
| type unitOpt string |
| |
| func (o unitOpt) applyFloat64Counter(c Float64CounterConfig) Float64CounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64UpDownCounter(c Float64UpDownCounterConfig) Float64UpDownCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64ObservableCounter(c Float64ObservableCounterConfig) Float64ObservableCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64ObservableUpDownCounter( |
| c Float64ObservableUpDownCounterConfig, |
| ) Float64ObservableUpDownCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyFloat64ObservableGauge(c Float64ObservableGaugeConfig) Float64ObservableGaugeConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64Counter(c Int64CounterConfig) Int64CounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64UpDownCounter(c Int64UpDownCounterConfig) Int64UpDownCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64ObservableUpDownCounter( |
| c Int64ObservableUpDownCounterConfig, |
| ) Int64ObservableUpDownCounterConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig { |
| c.unit = string(o) |
| return c |
| } |
| |
| // WithUnit sets the instrument unit. |
| // |
| // The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code. |
| func WithUnit(u string) InstrumentOption { return unitOpt(u) } |
| |
| // WithExplicitBucketBoundaries sets the instrument explicit bucket boundaries. |
| // |
| // This option is considered "advisory", and may be ignored by API implementations. |
| func WithExplicitBucketBoundaries(bounds ...float64) HistogramOption { return bucketOpt(bounds) } |
| |
| type bucketOpt []float64 |
| |
| func (o bucketOpt) applyFloat64Histogram(c Float64HistogramConfig) Float64HistogramConfig { |
| c.explicitBucketBoundaries = o |
| return c |
| } |
| |
| func (o bucketOpt) applyInt64Histogram(c Int64HistogramConfig) Int64HistogramConfig { |
| c.explicitBucketBoundaries = o |
| return c |
| } |
| |
| // AddOption applies options to an addition measurement. See |
| // [MeasurementOption] for other options that can be used as an AddOption. |
| type AddOption interface { |
| applyAdd(AddConfig) AddConfig |
| } |
| |
| // AddConfig contains options for an addition measurement. |
| type AddConfig struct { |
| attrs attribute.Set |
| } |
| |
| // NewAddConfig returns a new [AddConfig] with all opts applied. |
| func NewAddConfig(opts []AddOption) AddConfig { |
| config := AddConfig{attrs: *attribute.EmptySet()} |
| for _, o := range opts { |
| config = o.applyAdd(config) |
| } |
| return config |
| } |
| |
| // Attributes returns the configured attribute set. |
| func (c AddConfig) Attributes() attribute.Set { |
| return c.attrs |
| } |
| |
| // RecordOption applies options to an addition measurement. See |
| // [MeasurementOption] for other options that can be used as a RecordOption. |
| type RecordOption interface { |
| applyRecord(RecordConfig) RecordConfig |
| } |
| |
| // RecordConfig contains options for a recorded measurement. |
| type RecordConfig struct { |
| attrs attribute.Set |
| } |
| |
| // NewRecordConfig returns a new [RecordConfig] with all opts applied. |
| func NewRecordConfig(opts []RecordOption) RecordConfig { |
| config := RecordConfig{attrs: *attribute.EmptySet()} |
| for _, o := range opts { |
| config = o.applyRecord(config) |
| } |
| return config |
| } |
| |
| // Attributes returns the configured attribute set. |
| func (c RecordConfig) Attributes() attribute.Set { |
| return c.attrs |
| } |
| |
| // ObserveOption applies options to an addition measurement. See |
| // [MeasurementOption] for other options that can be used as a ObserveOption. |
| type ObserveOption interface { |
| applyObserve(ObserveConfig) ObserveConfig |
| } |
| |
| // ObserveConfig contains options for an observed measurement. |
| type ObserveConfig struct { |
| attrs attribute.Set |
| } |
| |
| // NewObserveConfig returns a new [ObserveConfig] with all opts applied. |
| func NewObserveConfig(opts []ObserveOption) ObserveConfig { |
| config := ObserveConfig{attrs: *attribute.EmptySet()} |
| for _, o := range opts { |
| config = o.applyObserve(config) |
| } |
| return config |
| } |
| |
| // Attributes returns the configured attribute set. |
| func (c ObserveConfig) Attributes() attribute.Set { |
| return c.attrs |
| } |
| |
| // MeasurementOption applies options to all instrument measurement. |
| type MeasurementOption interface { |
| AddOption |
| RecordOption |
| ObserveOption |
| } |
| |
| type attrOpt struct { |
| set attribute.Set |
| } |
| |
| // mergeSets returns the union of keys between a and b. Any duplicate keys will |
| // use the value associated with b. |
| func mergeSets(a, b attribute.Set) attribute.Set { |
| // NewMergeIterator uses the first value for any duplicates. |
| iter := attribute.NewMergeIterator(&b, &a) |
| merged := make([]attribute.KeyValue, 0, a.Len()+b.Len()) |
| for iter.Next() { |
| merged = append(merged, iter.Attribute()) |
| } |
| return attribute.NewSet(merged...) |
| } |
| |
| func (o attrOpt) applyAdd(c AddConfig) AddConfig { |
| switch { |
| case o.set.Len() == 0: |
| case c.attrs.Len() == 0: |
| c.attrs = o.set |
| default: |
| c.attrs = mergeSets(c.attrs, o.set) |
| } |
| return c |
| } |
| |
| func (o attrOpt) applyRecord(c RecordConfig) RecordConfig { |
| switch { |
| case o.set.Len() == 0: |
| case c.attrs.Len() == 0: |
| c.attrs = o.set |
| default: |
| c.attrs = mergeSets(c.attrs, o.set) |
| } |
| return c |
| } |
| |
| func (o attrOpt) applyObserve(c ObserveConfig) ObserveConfig { |
| switch { |
| case o.set.Len() == 0: |
| case c.attrs.Len() == 0: |
| c.attrs = o.set |
| default: |
| c.attrs = mergeSets(c.attrs, o.set) |
| } |
| return c |
| } |
| |
| // WithAttributeSet sets the attribute Set associated with a measurement is |
| // made with. |
| // |
| // If multiple WithAttributeSet or WithAttributes options are passed the |
| // attributes will be merged together in the order they are passed. Attributes |
| // with duplicate keys will use the last value passed. |
| func WithAttributeSet(attributes attribute.Set) MeasurementOption { |
| return attrOpt{set: attributes} |
| } |
| |
| // WithAttributes converts attributes into an attribute Set and sets the Set to |
| // be associated with a measurement. This is shorthand for: |
| // |
| // cp := make([]attribute.KeyValue, len(attributes)) |
| // copy(cp, attributes) |
| // WithAttributeSet(attribute.NewSet(cp...)) |
| // |
| // [attribute.NewSet] may modify the passed attributes so this will make a copy |
| // of attributes before creating a set in order to ensure this function is |
| // concurrent safe. This makes this option function less optimized in |
| // comparison to [WithAttributeSet]. Therefore, [WithAttributeSet] should be |
| // preferred for performance sensitive code. |
| // |
| // See [WithAttributeSet] for information about how multiple WithAttributes are |
| // merged. |
| func WithAttributes(attributes ...attribute.KeyValue) MeasurementOption { |
| cp := make([]attribute.KeyValue, len(attributes)) |
| copy(cp, attributes) |
| return attrOpt{set: attribute.NewSet(cp...)} |
| } |