blob: d0d488df13050fc0779d15b09182e91139b661c9 [file] [log] [blame]
Joey Armstronga6af1522023-01-17 16:06:16 -05001// 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
15package metric
16
17import (
18 "context"
19
20 "go.opentelemetry.io/otel/label"
21)
22
23// The file is organized as follows:
24//
25// - Observation type
26// - Three kinds of Observer callback (int64, float64, batch)
27// - Three kinds of Observer result (int64, float64, batch)
28// - Three kinds of Observe() function (int64, float64, batch)
29// - Three kinds of AsyncRunner interface (abstract, single, batch)
30// - Two kinds of Observer constructor (int64, float64)
31// - Two kinds of Observation() function (int64, float64)
32// - Various internals
33
34// Observation is used for reporting an asynchronous batch of metric
35// values. Instances of this type should be created by asynchronous
36// instruments (e.g., Int64ValueObserver.Observation()).
37type Observation struct {
38 // number needs to be aligned for 64-bit atomic operations.
39 number Number
40 instrument AsyncImpl
41}
42
43// Int64ObserverFunc is a type of callback that integral
44// observers run.
45type Int64ObserverFunc func(context.Context, Int64ObserverResult)
46
47// Float64ObserverFunc is a type of callback that floating point
48// observers run.
49type Float64ObserverFunc func(context.Context, Float64ObserverResult)
50
51// BatchObserverFunc is a callback argument for use with any
52// Observer instrument that will be reported as a batch of
53// observations.
54type BatchObserverFunc func(context.Context, BatchObserverResult)
55
56// Int64ObserverResult is passed to an observer callback to capture
57// observations for one asynchronous integer metric instrument.
58type Int64ObserverResult struct {
59 instrument AsyncImpl
60 function func([]label.KeyValue, ...Observation)
61}
62
63// Float64ObserverResult is passed to an observer callback to capture
64// observations for one asynchronous floating point metric instrument.
65type Float64ObserverResult struct {
66 instrument AsyncImpl
67 function func([]label.KeyValue, ...Observation)
68}
69
70// BatchObserverResult is passed to a batch observer callback to
71// capture observations for multiple asynchronous instruments.
72type BatchObserverResult struct {
73 function func([]label.KeyValue, ...Observation)
74}
75
76// Observe captures a single integer value from the associated
77// instrument callback, with the given labels.
78func (ir Int64ObserverResult) Observe(value int64, labels ...label.KeyValue) {
79 ir.function(labels, Observation{
80 instrument: ir.instrument,
81 number: NewInt64Number(value),
82 })
83}
84
85// Observe captures a single floating point value from the associated
86// instrument callback, with the given labels.
87func (fr Float64ObserverResult) Observe(value float64, labels ...label.KeyValue) {
88 fr.function(labels, Observation{
89 instrument: fr.instrument,
90 number: NewFloat64Number(value),
91 })
92}
93
94// Observe captures a multiple observations from the associated batch
95// instrument callback, with the given labels.
96func (br BatchObserverResult) Observe(labels []label.KeyValue, obs ...Observation) {
97 br.function(labels, obs...)
98}
99
100// AsyncRunner is expected to convert into an AsyncSingleRunner or an
101// AsyncBatchRunner. SDKs will encounter an error if the AsyncRunner
102// does not satisfy one of these interfaces.
103type AsyncRunner interface {
104 // AnyRunner() is a non-exported method with no functional use
105 // other than to make this a non-empty interface.
106 AnyRunner()
107}
108
109// AsyncSingleRunner is an interface implemented by single-observer
110// callbacks.
111type AsyncSingleRunner interface {
112 // Run accepts a single instrument and function for capturing
113 // observations of that instrument. Each call to the function
114 // receives one captured observation. (The function accepts
115 // multiple observations so the same implementation can be
116 // used for batch runners.)
117 Run(ctx context.Context, single AsyncImpl, capture func([]label.KeyValue, ...Observation))
118
119 AsyncRunner
120}
121
122// AsyncBatchRunner is an interface implemented by batch-observer
123// callbacks.
124type AsyncBatchRunner interface {
125 // Run accepts a function for capturing observations of
126 // multiple instruments.
127 Run(ctx context.Context, capture func([]label.KeyValue, ...Observation))
128
129 AsyncRunner
130}
131
132var _ AsyncSingleRunner = (*Int64ObserverFunc)(nil)
133var _ AsyncSingleRunner = (*Float64ObserverFunc)(nil)
134var _ AsyncBatchRunner = (*BatchObserverFunc)(nil)
135
136// newInt64AsyncRunner returns a single-observer callback for integer Observer instruments.
137func newInt64AsyncRunner(c Int64ObserverFunc) AsyncSingleRunner {
138 return &c
139}
140
141// newFloat64AsyncRunner returns a single-observer callback for floating point Observer instruments.
142func newFloat64AsyncRunner(c Float64ObserverFunc) AsyncSingleRunner {
143 return &c
144}
145
146// newBatchAsyncRunner returns a batch-observer callback use with multiple Observer instruments.
147func newBatchAsyncRunner(c BatchObserverFunc) AsyncBatchRunner {
148 return &c
149}
150
151// AnyRunner implements AsyncRunner.
152func (*Int64ObserverFunc) AnyRunner() {}
153
154// AnyRunner implements AsyncRunner.
155func (*Float64ObserverFunc) AnyRunner() {}
156
157// AnyRunner implements AsyncRunner.
158func (*BatchObserverFunc) AnyRunner() {}
159
160// Run implements AsyncSingleRunner.
161func (i *Int64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
162 (*i)(ctx, Int64ObserverResult{
163 instrument: impl,
164 function: function,
165 })
166}
167
168// Run implements AsyncSingleRunner.
169func (f *Float64ObserverFunc) Run(ctx context.Context, impl AsyncImpl, function func([]label.KeyValue, ...Observation)) {
170 (*f)(ctx, Float64ObserverResult{
171 instrument: impl,
172 function: function,
173 })
174}
175
176// Run implements AsyncBatchRunner.
177func (b *BatchObserverFunc) Run(ctx context.Context, function func([]label.KeyValue, ...Observation)) {
178 (*b)(ctx, BatchObserverResult{
179 function: function,
180 })
181}
182
183// wrapInt64ValueObserverInstrument converts an AsyncImpl into Int64ValueObserver.
184func wrapInt64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Int64ValueObserver, error) {
185 common, err := checkNewAsync(asyncInst, err)
186 return Int64ValueObserver{asyncInstrument: common}, err
187}
188
189// wrapFloat64ValueObserverInstrument converts an AsyncImpl into Float64ValueObserver.
190func wrapFloat64ValueObserverInstrument(asyncInst AsyncImpl, err error) (Float64ValueObserver, error) {
191 common, err := checkNewAsync(asyncInst, err)
192 return Float64ValueObserver{asyncInstrument: common}, err
193}
194
195// wrapInt64SumObserverInstrument converts an AsyncImpl into Int64SumObserver.
196func wrapInt64SumObserverInstrument(asyncInst AsyncImpl, err error) (Int64SumObserver, error) {
197 common, err := checkNewAsync(asyncInst, err)
198 return Int64SumObserver{asyncInstrument: common}, err
199}
200
201// wrapFloat64SumObserverInstrument converts an AsyncImpl into Float64SumObserver.
202func wrapFloat64SumObserverInstrument(asyncInst AsyncImpl, err error) (Float64SumObserver, error) {
203 common, err := checkNewAsync(asyncInst, err)
204 return Float64SumObserver{asyncInstrument: common}, err
205}
206
207// wrapInt64UpDownSumObserverInstrument converts an AsyncImpl into Int64UpDownSumObserver.
208func wrapInt64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Int64UpDownSumObserver, error) {
209 common, err := checkNewAsync(asyncInst, err)
210 return Int64UpDownSumObserver{asyncInstrument: common}, err
211}
212
213// wrapFloat64UpDownSumObserverInstrument converts an AsyncImpl into Float64UpDownSumObserver.
214func wrapFloat64UpDownSumObserverInstrument(asyncInst AsyncImpl, err error) (Float64UpDownSumObserver, error) {
215 common, err := checkNewAsync(asyncInst, err)
216 return Float64UpDownSumObserver{asyncInstrument: common}, err
217}