| 
									
										
										
										
											2023-05-09 19:19:48 +02:00
										 |  |  | // Copyright The OpenTelemetry Authors | 
					
						
							| 
									
										
										
										
											2024-04-11 11:46:18 +02:00
										 |  |  | // SPDX-License-Identifier: Apache-2.0 | 
					
						
							| 
									
										
										
										
											2023-05-09 19:19:48 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* | 
					
						
							| 
									
										
										
										
											2023-06-05 10:15:05 +02:00
										 |  |  | Package metric provides the OpenTelemetry API used to measure metrics about | 
					
						
							|  |  |  | source code operation. | 
					
						
							| 
									
										
										
										
											2023-05-09 19:19:48 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-05 10:15:05 +02:00
										 |  |  | This API is separate from its implementation so the instrumentation built from | 
					
						
							|  |  |  | it is reusable. See [go.opentelemetry.io/otel/sdk/metric] for the official | 
					
						
							|  |  |  | OpenTelemetry implementation of this API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All measurements made with this package are made via instruments. These | 
					
						
							|  |  |  | instruments are created by a [Meter] which itself is created by a | 
					
						
							|  |  |  | [MeterProvider]. Applications need to accept a [MeterProvider] implementation | 
					
						
							|  |  |  | as a starting point when instrumenting. This can be done directly, or by using | 
					
						
							|  |  |  | the OpenTelemetry global MeterProvider via [GetMeterProvider]. Using an | 
					
						
							|  |  |  | appropriately named [Meter] from the accepted [MeterProvider], instrumentation | 
					
						
							|  |  |  | can then be built from the [Meter]'s instruments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Instruments | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Each instrument is designed to make measurements of a particular type. Broadly, | 
					
						
							|  |  |  | all instruments fall into two overlapping logical categories: asynchronous or | 
					
						
							|  |  |  | synchronous, and int64 or float64. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All synchronous instruments ([Int64Counter], [Int64UpDownCounter], | 
					
						
							|  |  |  | [Int64Histogram], [Float64Counter], [Float64UpDownCounter], and | 
					
						
							|  |  |  | [Float64Histogram]) are used to measure the operation and performance of source | 
					
						
							|  |  |  | code during the source code execution. These instruments only make measurements | 
					
						
							|  |  |  | when the source code they instrument is run. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All asynchronous instruments ([Int64ObservableCounter], | 
					
						
							|  |  |  | [Int64ObservableUpDownCounter], [Int64ObservableGauge], | 
					
						
							|  |  |  | [Float64ObservableCounter], [Float64ObservableUpDownCounter], and | 
					
						
							|  |  |  | [Float64ObservableGauge]) are used to measure metrics outside of the execution | 
					
						
							|  |  |  | of source code. They are said to make "observations" via a callback function | 
					
						
							|  |  |  | called once every measurement collection cycle. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Each instrument is also grouped by the value type it measures. Either int64 or | 
					
						
							|  |  |  | float64. The value being measured will dictate which instrument in these | 
					
						
							|  |  |  | categories to use. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Outside of these two broad categories, instruments are described by the | 
					
						
							|  |  |  | function they are designed to serve. All Counters ([Int64Counter], | 
					
						
							|  |  |  | [Float64Counter], [Int64ObservableCounter], and [Float64ObservableCounter]) are | 
					
						
							|  |  |  | designed to measure values that never decrease in value, but instead only | 
					
						
							|  |  |  | incrementally increase in value. UpDownCounters ([Int64UpDownCounter], | 
					
						
							|  |  |  | [Float64UpDownCounter], [Int64ObservableUpDownCounter], and | 
					
						
							|  |  |  | [Float64ObservableUpDownCounter]) on the other hand, are designed to measure | 
					
						
							|  |  |  | values that can increase and decrease. When more information needs to be | 
					
						
							|  |  |  | conveyed about all the synchronous measurements made during a collection cycle, | 
					
						
							|  |  |  | a Histogram ([Int64Histogram] and [Float64Histogram]) should be used. Finally, | 
					
						
							|  |  |  | when just the most recent measurement needs to be conveyed about an | 
					
						
							|  |  |  | asynchronous measurement, a Gauge ([Int64ObservableGauge] and | 
					
						
							|  |  |  | [Float64ObservableGauge]) should be used. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | See the [OpenTelemetry documentation] for more information about instruments | 
					
						
							|  |  |  | and their intended use. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # Measurements | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Measurements are made by recording values and information about the values with | 
					
						
							|  |  |  | an instrument. How these measurements are recorded depends on the instrument. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Measurements for synchronous instruments ([Int64Counter], [Int64UpDownCounter], | 
					
						
							|  |  |  | [Int64Histogram], [Float64Counter], [Float64UpDownCounter], and | 
					
						
							|  |  |  | [Float64Histogram]) are recorded using the instrument methods directly. All | 
					
						
							|  |  |  | counter instruments have an Add method that is used to measure an increment | 
					
						
							|  |  |  | value, and all histogram instruments have a Record method to measure a data | 
					
						
							|  |  |  | point. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Asynchronous instruments ([Int64ObservableCounter], | 
					
						
							|  |  |  | [Int64ObservableUpDownCounter], [Int64ObservableGauge], | 
					
						
							|  |  |  | [Float64ObservableCounter], [Float64ObservableUpDownCounter], and | 
					
						
							|  |  |  | [Float64ObservableGauge]) record measurements within a callback function. The | 
					
						
							|  |  |  | callback is registered with the Meter which ensures the callback is called once | 
					
						
							|  |  |  | per collection cycle. A callback can be registered two ways: during the | 
					
						
							|  |  |  | instrument's creation using an option, or later using the RegisterCallback | 
					
						
							|  |  |  | method of the [Meter] that created the instrument. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the following criteria are met, an option ([WithInt64Callback] or | 
					
						
							|  |  |  | [WithFloat64Callback]) can be used during the asynchronous instrument's | 
					
						
							|  |  |  | creation to register a callback ([Int64Callback] or [Float64Callback], | 
					
						
							|  |  |  | respectively): | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - The measurement process is known when the instrument is created | 
					
						
							|  |  |  |   - Only that instrument will make a measurement within the callback | 
					
						
							|  |  |  |   - The callback never needs to be unregistered | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If the criteria are not met, use the RegisterCallback method of the [Meter] that | 
					
						
							|  |  |  | created the instrument to register a [Callback]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # API Implementations | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This package does not conform to the standard Go versioning policy, all of its | 
					
						
							|  |  |  | interfaces may have methods added to them without a package major version bump. | 
					
						
							|  |  |  | This non-standard API evolution could surprise an uninformed implementation | 
					
						
							|  |  |  | author. They could unknowingly build their implementation in a way that would | 
					
						
							|  |  |  | result in a runtime panic for their users that update to the new API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The API is designed to help inform an instrumentation author about this | 
					
						
							|  |  |  | non-standard API evolution. It requires them to choose a default behavior for | 
					
						
							|  |  |  | unimplemented interface methods. There are three behavior choices they can | 
					
						
							|  |  |  | make: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   - Compilation failure | 
					
						
							|  |  |  |   - Panic | 
					
						
							|  |  |  |   - Default to another implementation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | All interfaces in this API embed a corresponding interface from | 
					
						
							|  |  |  | [go.opentelemetry.io/otel/metric/embedded]. If an author wants the default | 
					
						
							|  |  |  | behavior of their implementations to be a compilation failure, signaling to | 
					
						
							|  |  |  | their users they need to update to the latest version of that implementation, | 
					
						
							|  |  |  | they need to embed the corresponding interface from | 
					
						
							|  |  |  | [go.opentelemetry.io/otel/metric/embedded] in their implementation. For | 
					
						
							|  |  |  | example, | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	import "go.opentelemetry.io/otel/metric/embedded" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	type MeterProvider struct { | 
					
						
							|  |  |  | 		embedded.MeterProvider | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If an author wants the default behavior of their implementations to a panic, | 
					
						
							|  |  |  | they need to embed the API interface directly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	import "go.opentelemetry.io/otel/metric" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	type MeterProvider struct { | 
					
						
							|  |  |  | 		metric.MeterProvider | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This is not a recommended behavior as it could lead to publishing packages that | 
					
						
							|  |  |  | contain runtime panics when users update other package that use newer versions | 
					
						
							|  |  |  | of [go.opentelemetry.io/otel/metric]. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Finally, an author can embed another implementation in theirs. The embedded | 
					
						
							|  |  |  | implementation will be used for methods not defined by the author. For example, | 
					
						
							| 
									
										
										
										
											2023-11-13 11:08:02 +01:00
										 |  |  | an author who wants to default to silently dropping the call can use | 
					
						
							| 
									
										
										
										
											2023-06-05 10:15:05 +02:00
										 |  |  | [go.opentelemetry.io/otel/metric/noop]: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	import "go.opentelemetry.io/otel/metric/noop" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	type MeterProvider struct { | 
					
						
							|  |  |  | 		noop.MeterProvider | 
					
						
							|  |  |  | 		// ... | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It is strongly recommended that authors only embed | 
					
						
							|  |  |  | [go.opentelemetry.io/otel/metric/noop] if they choose this default behavior. | 
					
						
							|  |  |  | That implementation is the only one OpenTelemetry authors can guarantee will | 
					
						
							|  |  |  | fully implement all the API interfaces when a user updates their API. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | [OpenTelemetry documentation]: https://opentelemetry.io/docs/concepts/signals/metrics/ | 
					
						
							|  |  |  | [GetMeterProvider]: https://pkg.go.dev/go.opentelemetry.io/otel#GetMeterProvider | 
					
						
							| 
									
										
										
										
											2023-05-09 19:19:48 +02:00
										 |  |  | */ | 
					
						
							|  |  |  | package metric // import "go.opentelemetry.io/otel/metric" |