2021-09-13 18:14:32 +02:00
|
|
|
// Copyright The OpenTelemetry Authors
|
2024-02-29 08:05:28 +02:00
|
|
|
// SPDX-License-Identifier: Apache-2.0
|
2021-09-13 18:14:32 +02:00
|
|
|
|
2023-04-27 20:25:48 +02:00
|
|
|
package metric // import "go.opentelemetry.io/otel/metric"
|
2021-09-13 18:14:32 +02:00
|
|
|
|
2023-04-18 16:16:06 +02:00
|
|
|
import "go.opentelemetry.io/otel/attribute"
|
|
|
|
|
2023-03-20 22:26:17 +02:00
|
|
|
// Observable is used as a grouping mechanism for all instruments that are
|
|
|
|
// updated within a Callback.
|
|
|
|
type Observable interface {
|
|
|
|
observable()
|
2021-09-13 18:14:32 +02:00
|
|
|
}
|
2023-01-06 19:20:49 +02:00
|
|
|
|
2023-04-27 20:25:48 +02:00
|
|
|
// InstrumentOption applies options to all instruments.
|
|
|
|
type InstrumentOption interface {
|
2023-03-21 15:16:57 +02:00
|
|
|
Int64CounterOption
|
|
|
|
Int64UpDownCounterOption
|
|
|
|
Int64HistogramOption
|
2024-05-16 18:56:40 +02:00
|
|
|
Int64GaugeOption
|
2023-03-21 15:16:57 +02:00
|
|
|
Int64ObservableCounterOption
|
|
|
|
Int64ObservableUpDownCounterOption
|
|
|
|
Int64ObservableGaugeOption
|
|
|
|
|
|
|
|
Float64CounterOption
|
|
|
|
Float64UpDownCounterOption
|
|
|
|
Float64HistogramOption
|
2024-05-16 18:56:40 +02:00
|
|
|
Float64GaugeOption
|
2023-03-21 15:16:57 +02:00
|
|
|
Float64ObservableCounterOption
|
|
|
|
Float64ObservableUpDownCounterOption
|
|
|
|
Float64ObservableGaugeOption
|
2023-01-06 19:20:49 +02:00
|
|
|
}
|
|
|
|
|
2023-10-26 19:18:37 +02:00
|
|
|
// HistogramOption applies options to histogram instruments.
|
|
|
|
type HistogramOption interface {
|
|
|
|
Int64HistogramOption
|
|
|
|
Float64HistogramOption
|
|
|
|
}
|
|
|
|
|
2023-01-06 19:20:49 +02:00
|
|
|
type descOpt string
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-05-16 18:56:40 +02:00
|
|
|
func (o descOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {
|
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
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 {
|
2023-01-06 19:20:49 +02:00
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2024-05-16 18:56:40 +02:00
|
|
|
func (o descOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {
|
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o descOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {
|
2023-01-06 19:20:49 +02:00
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o descOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
|
2023-01-06 19:20:49 +02:00
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o descOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {
|
2023-01-06 19:20:49 +02:00
|
|
|
c.description = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithDescription sets the instrument description.
|
2023-04-27 20:25:48 +02:00
|
|
|
func WithDescription(desc string) InstrumentOption { return descOpt(desc) }
|
2023-01-06 19:20:49 +02:00
|
|
|
|
2023-02-27 18:10:56 +02:00
|
|
|
type unitOpt string
|
2023-01-06 19:20:49 +02:00
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2024-05-16 18:56:40 +02:00
|
|
|
func (o unitOpt) applyFloat64Gauge(c Float64GaugeConfig) Float64GaugeConfig {
|
|
|
|
c.unit = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
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 {
|
2023-02-27 18:10:56 +02:00
|
|
|
c.unit = string(o)
|
2023-01-06 19:20:49 +02:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2024-05-16 18:56:40 +02:00
|
|
|
func (o unitOpt) applyInt64Gauge(c Int64GaugeConfig) Int64GaugeConfig {
|
|
|
|
c.unit = string(o)
|
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o unitOpt) applyInt64ObservableCounter(c Int64ObservableCounterConfig) Int64ObservableCounterConfig {
|
2023-02-27 18:10:56 +02:00
|
|
|
c.unit = string(o)
|
2023-01-06 19:20:49 +02:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o unitOpt) applyInt64ObservableUpDownCounter(c Int64ObservableUpDownCounterConfig) Int64ObservableUpDownCounterConfig {
|
2023-02-27 18:10:56 +02:00
|
|
|
c.unit = string(o)
|
2023-01-06 19:20:49 +02:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
2023-03-21 15:16:57 +02:00
|
|
|
func (o unitOpt) applyInt64ObservableGauge(c Int64ObservableGaugeConfig) Int64ObservableGaugeConfig {
|
2023-02-27 18:10:56 +02:00
|
|
|
c.unit = string(o)
|
2023-01-06 19:20:49 +02:00
|
|
|
return c
|
|
|
|
}
|
|
|
|
|
|
|
|
// WithUnit sets the instrument unit.
|
2023-08-08 14:16:58 +02:00
|
|
|
//
|
|
|
|
// The unit u should be defined using the appropriate [UCUM](https://ucum.org) case-sensitive code.
|
2023-04-27 20:25:48 +02:00
|
|
|
func WithUnit(u string) InstrumentOption { return unitOpt(u) }
|
2023-04-18 16:16:06 +02:00
|
|
|
|
2023-10-26 19:18:37 +02:00
|
|
|
// 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
|
|
|
|
}
|
|
|
|
|
2023-04-18 16:16:06 +02:00
|
|
|
// AddOption applies options to an addition measurement. See
|
2023-05-08 22:00:27 +02:00
|
|
|
// [MeasurementOption] for other options that can be used as an AddOption.
|
2023-04-18 16:16:06 +02:00
|
|
|
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)
|
|
|
|
// WithAttributes(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...)}
|
|
|
|
}
|