...

Source file src/go.opentelemetry.io/otel/metric/instrument.go

Documentation: go.opentelemetry.io/otel/metric

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

View as plain text