doc.go

  1// Copyright The OpenTelemetry Authors
  2// SPDX-License-Identifier: Apache-2.0
  3
  4/*
  5Package metric provides the OpenTelemetry API used to measure metrics about
  6source code operation.
  7
  8This API is separate from its implementation so the instrumentation built from
  9it is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official
 10OpenTelemetry implementation of this API.
 11
 12All measurements made with this package are made via instruments. These
 13instruments are created by a [Meter] which itself is created by a
 14[MeterProvider]. Applications need to accept a [MeterProvider] implementation
 15as a starting point when instrumenting. This can be done directly, or by using
 16the OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an
 17appropriately named [Meter] from the accepted [MeterProvider], instrumentation
 18can then be built from the [Meter]'s instruments.
 19
 20# Instruments
 21
 22Each instrument is designed to make measurements of a particular type. Broadly,
 23all instruments fall into two overlapping logical categories: asynchronous or
 24synchronous, and int64 or float64.
 25
 26All synchronous instruments ([Int64Counter], [Int64UpDownCounter],
 27[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
 28[Float64Histogram]) are used to measure the operation and performance of source
 29code during the source code execution. These instruments only make measurements
 30when the source code they instrument is run.
 31
 32All asynchronous instruments ([Int64ObservableCounter],
 33[Int64ObservableUpDownCounter], [Int64ObservableGauge],
 34[Float64ObservableCounter], [Float64ObservableUpDownCounter], and
 35[Float64ObservableGauge]) are used to measure metrics outside of the execution
 36of source code. They are said to make "observations" via a callback function
 37called once every measurement collection cycle.
 38
 39Each instrument is also grouped by the value type it measures. Either int64 or
 40float64. The value being measured will dictate which instrument in these
 41categories to use.
 42
 43Outside of these two broad categories, instruments are described by the
 44function they are designed to serve. All Counters ([Int64Counter],
 45[Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are
 46designed to measure values that never decrease in value, but instead only
 47incrementally increase in value. UpDownCounters ([Int64UpDownCounter],
 48[Float64UpDownCounter], [Int64ObservableUpDownCounter], and
 49[Float64ObservableUpDownCounter]) on the other hand, are designed to measure
 50values that can increase and decrease. When more information needs to be
 51conveyed about all the synchronous measurements made during a collection cycle,
 52a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally,
 53when just the most recent measurement needs to be conveyed about an
 54asynchronous measurement, a Gauge ([Int64ObservableGauge] and
 55[Float64ObservableGauge]) should be used.
 56
 57See the [OpenTelemetry documentation] for more information about instruments
 58and their intended use.
 59
 60# Instrument Name
 61
 62OpenTelemetry defines an [instrument name syntax] that restricts what
 63instrument names are allowed.
 64
 65Instrument names should ...
 66
 67  - Not be empty.
 68  - Have an alphabetic character as their first letter.
 69  - Have any letter after the first be an alphanumeric character, ‘_’, ‘.’,
 70    ‘-’, or ‘/’.
 71  - Have a maximum length of 255 letters.
 72
 73To ensure compatibility with observability platforms, all instruments created
 74need to conform to this syntax. Not all implementations of the API will validate
 75these names, it is the callers responsibility to ensure compliance.
 76
 77# Measurements
 78
 79Measurements are made by recording values and information about the values with
 80an instrument. How these measurements are recorded depends on the instrument.
 81
 82Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter],
 83[Int64Histogram], [Float64Counter], [Float64UpDownCounter], and
 84[Float64Histogram]) are recorded using the instrument methods directly. All
 85counter instruments have an Add method that is used to measure an increment
 86value, and all histogram instruments have a Record method to measure a data
 87point.
 88
 89Asynchronous instruments ([Int64ObservableCounter],
 90[Int64ObservableUpDownCounter], [Int64ObservableGauge],
 91[Float64ObservableCounter], [Float64ObservableUpDownCounter], and
 92[Float64ObservableGauge]) record measurements within a callback function. The
 93callback is registered with the Meter which ensures the callback is called once
 94per collection cycle. A callback can be registered two ways: during the
 95instrument's creation using an option, or later using the RegisterCallback
 96method of the [Meter] that created the instrument.
 97
 98If the following criteria are met, an option ([WithInt64Callback] or
 99[WithFloat64Callback]) can be used during the asynchronous instrument's
100creation to register a callback ([Int64Callback] or [Float64Callback],
101respectively):
102
103  - The measurement process is known when the instrument is created
104  - Only that instrument will make a measurement within the callback
105  - The callback never needs to be unregistered
106
107If the criteria are not met, use the RegisterCallback method of the [Meter] that
108created the instrument to register a [Callback].
109
110# API Implementations
111
112This package does not conform to the standard Go versioning policy, all of its
113interfaces may have methods added to them without a package major version bump.
114This non-standard API evolution could surprise an uninformed implementation
115author. They could unknowingly build their implementation in a way that would
116result in a runtime panic for their users that update to the new API.
117
118The API is designed to help inform an instrumentation author about this
119non-standard API evolution. It requires them to choose a default behavior for
120unimplemented interface methods. There are three behavior choices they can
121make:
122
123  - Compilation failure
124  - Panic
125  - Default to another implementation
126
127All interfaces in this API embed a corresponding interface from
128[go.opentelemetry.io/otel/metric/embedded]. If an author wants the default
129behavior of their implementations to be a compilation failure, signaling to
130their users they need to update to the latest version of that implementation,
131they need to embed the corresponding interface from
132[go.opentelemetry.io/otel/metric/embedded] in their implementation. For
133example,
134
135	import "go.opentelemetry.io/otel/metric/embedded"
136
137	type MeterProvider struct {
138		embedded.MeterProvider
139		// ...
140	}
141
142If an author wants the default behavior of their implementations to a panic,
143they need to embed the API interface directly.
144
145	import "go.opentelemetry.io/otel/metric"
146
147	type MeterProvider struct {
148		metric.MeterProvider
149		// ...
150	}
151
152This is not a recommended behavior as it could lead to publishing packages that
153contain runtime panics when users update other package that use newer versions
154of [go.opentelemetry.io/otel/metric].
155
156Finally, an author can embed another implementation in theirs. The embedded
157implementation will be used for methods not defined by the author. For example,
158an author who wants to default to silently dropping the call can use
159[go.opentelemetry.io/otel/metric/noop]:
160
161	import "go.opentelemetry.io/otel/metric/noop"
162
163	type MeterProvider struct {
164		noop.MeterProvider
165		// ...
166	}
167
168It is strongly recommended that authors only embed
169[go.opentelemetry.io/otel/metric/noop] if they choose this default behavior.
170That implementation is the only one OpenTelemetry authors can guarantee will
171fully implement all the API interfaces when a user updates their API.
172
173[instrument name syntax]: https://opentelemetry.io/docs/specs/otel/metrics/api/#instrument-name-syntax
174[OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/
175[GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider
176*/
177package metric // import "go.opentelemetry.io/otel/metric"