blob: a08a65ba1277f752f22a84d3f1d2cad6d2b4d643 [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 "errors"
20
21 "go.opentelemetry.io/otel/label"
22)
23
24// ErrSDKReturnedNilImpl is returned when a new `MeterImpl` returns nil.
25var ErrSDKReturnedNilImpl = errors.New("SDK returned a nil implementation")
26
27// Measurement is used for reporting a synchronous batch of metric
28// values. Instances of this type should be created by synchronous
29// instruments (e.g., Int64Counter.Measurement()).
30type Measurement struct {
31 // number needs to be aligned for 64-bit atomic operations.
32 number Number
33 instrument SyncImpl
34}
35
36// syncInstrument contains a SyncImpl.
37type syncInstrument struct {
38 instrument SyncImpl
39}
40
41// syncBoundInstrument contains a BoundSyncImpl.
42type syncBoundInstrument struct {
43 boundInstrument BoundSyncImpl
44}
45
46// asyncInstrument contains a AsyncImpl.
47type asyncInstrument struct {
48 instrument AsyncImpl
49}
50
51// SyncImpl returns the instrument that created this measurement.
52// This returns an implementation-level object for use by the SDK,
53// users should not refer to this.
54func (m Measurement) SyncImpl() SyncImpl {
55 return m.instrument
56}
57
58// Number returns a number recorded in this measurement.
59func (m Measurement) Number() Number {
60 return m.number
61}
62
63// AsyncImpl returns the instrument that created this observation.
64// This returns an implementation-level object for use by the SDK,
65// users should not refer to this.
66func (m Observation) AsyncImpl() AsyncImpl {
67 return m.instrument
68}
69
70// Number returns a number recorded in this observation.
71func (m Observation) Number() Number {
72 return m.number
73}
74
75// AsyncImpl implements AsyncImpl.
76func (a asyncInstrument) AsyncImpl() AsyncImpl {
77 return a.instrument
78}
79
80// SyncImpl returns the implementation object for synchronous instruments.
81func (s syncInstrument) SyncImpl() SyncImpl {
82 return s.instrument
83}
84
85func (s syncInstrument) bind(labels []label.KeyValue) syncBoundInstrument {
86 return newSyncBoundInstrument(s.instrument.Bind(labels))
87}
88
89func (s syncInstrument) float64Measurement(value float64) Measurement {
90 return newMeasurement(s.instrument, NewFloat64Number(value))
91}
92
93func (s syncInstrument) int64Measurement(value int64) Measurement {
94 return newMeasurement(s.instrument, NewInt64Number(value))
95}
96
97func (s syncInstrument) directRecord(ctx context.Context, number Number, labels []label.KeyValue) {
98 s.instrument.RecordOne(ctx, number, labels)
99}
100
101func (h syncBoundInstrument) directRecord(ctx context.Context, number Number) {
102 h.boundInstrument.RecordOne(ctx, number)
103}
104
105// Unbind calls SyncImpl.Unbind.
106func (h syncBoundInstrument) Unbind() {
107 h.boundInstrument.Unbind()
108}
109
110// checkNewAsync receives an AsyncImpl and potential
111// error, and returns the same types, checking for and ensuring that
112// the returned interface is not nil.
113func checkNewAsync(instrument AsyncImpl, err error) (asyncInstrument, error) {
114 if instrument == nil {
115 if err == nil {
116 err = ErrSDKReturnedNilImpl
117 }
118 instrument = NoopAsync{}
119 }
120 return asyncInstrument{
121 instrument: instrument,
122 }, err
123}
124
125// checkNewSync receives an SyncImpl and potential
126// error, and returns the same types, checking for and ensuring that
127// the returned interface is not nil.
128func checkNewSync(instrument SyncImpl, err error) (syncInstrument, error) {
129 if instrument == nil {
130 if err == nil {
131 err = ErrSDKReturnedNilImpl
132 }
133 // Note: an alternate behavior would be to synthesize a new name
134 // or group all duplicately-named instruments of a certain type
135 // together and use a tag for the original name, e.g.,
136 // name = 'invalid.counter.int64'
137 // label = 'original-name=duplicate-counter-name'
138 instrument = NoopSync{}
139 }
140 return syncInstrument{
141 instrument: instrument,
142 }, err
143}
144
145func newSyncBoundInstrument(boundInstrument BoundSyncImpl) syncBoundInstrument {
146 return syncBoundInstrument{
147 boundInstrument: boundInstrument,
148 }
149}
150
151func newMeasurement(instrument SyncImpl, number Number) Measurement {
152 return Measurement{
153 instrument: instrument,
154 number: number,
155 }
156}
157
158// wrapInt64CounterInstrument converts a SyncImpl into Int64Counter.
159func wrapInt64CounterInstrument(syncInst SyncImpl, err error) (Int64Counter, error) {
160 common, err := checkNewSync(syncInst, err)
161 return Int64Counter{syncInstrument: common}, err
162}
163
164// wrapFloat64CounterInstrument converts a SyncImpl into Float64Counter.
165func wrapFloat64CounterInstrument(syncInst SyncImpl, err error) (Float64Counter, error) {
166 common, err := checkNewSync(syncInst, err)
167 return Float64Counter{syncInstrument: common}, err
168}
169
170// wrapInt64UpDownCounterInstrument converts a SyncImpl into Int64UpDownCounter.
171func wrapInt64UpDownCounterInstrument(syncInst SyncImpl, err error) (Int64UpDownCounter, error) {
172 common, err := checkNewSync(syncInst, err)
173 return Int64UpDownCounter{syncInstrument: common}, err
174}
175
176// wrapFloat64UpDownCounterInstrument converts a SyncImpl into Float64UpDownCounter.
177func wrapFloat64UpDownCounterInstrument(syncInst SyncImpl, err error) (Float64UpDownCounter, error) {
178 common, err := checkNewSync(syncInst, err)
179 return Float64UpDownCounter{syncInstrument: common}, err
180}
181
182// wrapInt64ValueRecorderInstrument converts a SyncImpl into Int64ValueRecorder.
183func wrapInt64ValueRecorderInstrument(syncInst SyncImpl, err error) (Int64ValueRecorder, error) {
184 common, err := checkNewSync(syncInst, err)
185 return Int64ValueRecorder{syncInstrument: common}, err
186}
187
188// wrapFloat64ValueRecorderInstrument converts a SyncImpl into Float64ValueRecorder.
189func wrapFloat64ValueRecorderInstrument(syncInst SyncImpl, err error) (Float64ValueRecorder, error) {
190 common, err := checkNewSync(syncInst, err)
191 return Float64ValueRecorder{syncInstrument: common}, err
192}