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