1// 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 // import "go.opentelemetry.io/otel/metric"
16
17import (
18	"context"
19
20	"go.opentelemetry.io/otel/label"
21	"go.opentelemetry.io/otel/metric/number"
22	"go.opentelemetry.io/otel/unit"
23)
24
25// MeterProvider supports named Meter instances.
26type MeterProvider interface {
27	// Meter creates an implementation of the Meter interface.
28	// The instrumentationName must be the name of the library providing
29	// instrumentation. This name may be the same as the instrumented code
30	// only if that code provides built-in instrumentation. If the
31	// instrumentationName is empty, then a implementation defined default
32	// name will be used instead.
33	Meter(instrumentationName string, opts ...MeterOption) Meter
34}
35
36// Meter is the creator of metric instruments.
37//
38// An uninitialized Meter is a no-op implementation.
39type Meter struct {
40	impl          MeterImpl
41	name, version string
42}
43
44// RecordBatch atomically records a batch of measurements.
45func (m Meter) RecordBatch(ctx context.Context, ls []label.KeyValue, ms ...Measurement) {
46	if m.impl == nil {
47		return
48	}
49	m.impl.RecordBatch(ctx, ls, ms...)
50}
51
52// NewBatchObserver creates a new BatchObserver that supports
53// making batches of observations for multiple instruments.
54func (m Meter) NewBatchObserver(callback BatchObserverFunc) BatchObserver {
55	return BatchObserver{
56		meter:  m,
57		runner: newBatchAsyncRunner(callback),
58	}
59}
60
61// NewInt64Counter creates a new integer Counter instrument with the
62// given name, customized with options.  May return an error if the
63// name is invalid (e.g., empty) or improperly registered (e.g.,
64// duplicate registration).
65func (m Meter) NewInt64Counter(name string, options ...InstrumentOption) (Int64Counter, error) {
66	return wrapInt64CounterInstrument(
67		m.newSync(name, CounterInstrumentKind, number.Int64Kind, options))
68}
69
70// NewFloat64Counter creates a new floating point Counter with the
71// given name, customized with options.  May return an error if the
72// name is invalid (e.g., empty) or improperly registered (e.g.,
73// duplicate registration).
74func (m Meter) NewFloat64Counter(name string, options ...InstrumentOption) (Float64Counter, error) {
75	return wrapFloat64CounterInstrument(
76		m.newSync(name, CounterInstrumentKind, number.Float64Kind, options))
77}
78
79// NewInt64UpDownCounter creates a new integer UpDownCounter instrument with the
80// given name, customized with options.  May return an error if the
81// name is invalid (e.g., empty) or improperly registered (e.g.,
82// duplicate registration).
83func (m Meter) NewInt64UpDownCounter(name string, options ...InstrumentOption) (Int64UpDownCounter, error) {
84	return wrapInt64UpDownCounterInstrument(
85		m.newSync(name, UpDownCounterInstrumentKind, number.Int64Kind, options))
86}
87
88// NewFloat64UpDownCounter creates a new floating point UpDownCounter with the
89// given name, customized with options.  May return an error if the
90// name is invalid (e.g., empty) or improperly registered (e.g.,
91// duplicate registration).
92func (m Meter) NewFloat64UpDownCounter(name string, options ...InstrumentOption) (Float64UpDownCounter, error) {
93	return wrapFloat64UpDownCounterInstrument(
94		m.newSync(name, UpDownCounterInstrumentKind, number.Float64Kind, options))
95}
96
97// NewInt64ValueRecorder creates a new integer ValueRecorder instrument with the
98// given name, customized with options.  May return an error if the
99// name is invalid (e.g., empty) or improperly registered (e.g.,
100// duplicate registration).
101func (m Meter) NewInt64ValueRecorder(name string, opts ...InstrumentOption) (Int64ValueRecorder, error) {
102	return wrapInt64ValueRecorderInstrument(
103		m.newSync(name, ValueRecorderInstrumentKind, number.Int64Kind, opts))
104}
105
106// NewFloat64ValueRecorder creates a new floating point ValueRecorder with the
107// given name, customized with options.  May return an error if the
108// name is invalid (e.g., empty) or improperly registered (e.g.,
109// duplicate registration).
110func (m Meter) NewFloat64ValueRecorder(name string, opts ...InstrumentOption) (Float64ValueRecorder, error) {
111	return wrapFloat64ValueRecorderInstrument(
112		m.newSync(name, ValueRecorderInstrumentKind, number.Float64Kind, opts))
113}
114
115// NewInt64ValueObserver creates a new integer ValueObserver instrument
116// with the given name, running a given callback, and customized with
117// options.  May return an error if the name is invalid (e.g., empty)
118// or improperly registered (e.g., duplicate registration).
119func (m Meter) NewInt64ValueObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64ValueObserver, error) {
120	if callback == nil {
121		return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
122	}
123	return wrapInt64ValueObserverInstrument(
124		m.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts,
125			newInt64AsyncRunner(callback)))
126}
127
128// NewFloat64ValueObserver creates a new floating point ValueObserver with
129// the given name, running a given callback, and customized with
130// options.  May return an error if the name is invalid (e.g., empty)
131// or improperly registered (e.g., duplicate registration).
132func (m Meter) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64ValueObserver, error) {
133	if callback == nil {
134		return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
135	}
136	return wrapFloat64ValueObserverInstrument(
137		m.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts,
138			newFloat64AsyncRunner(callback)))
139}
140
141// NewInt64SumObserver creates a new integer SumObserver instrument
142// with the given name, running a given callback, and customized with
143// options.  May return an error if the name is invalid (e.g., empty)
144// or improperly registered (e.g., duplicate registration).
145func (m Meter) NewInt64SumObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64SumObserver, error) {
146	if callback == nil {
147		return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
148	}
149	return wrapInt64SumObserverInstrument(
150		m.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts,
151			newInt64AsyncRunner(callback)))
152}
153
154// NewFloat64SumObserver creates a new floating point SumObserver with
155// the given name, running a given callback, and customized with
156// options.  May return an error if the name is invalid (e.g., empty)
157// or improperly registered (e.g., duplicate registration).
158func (m Meter) NewFloat64SumObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64SumObserver, error) {
159	if callback == nil {
160		return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
161	}
162	return wrapFloat64SumObserverInstrument(
163		m.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts,
164			newFloat64AsyncRunner(callback)))
165}
166
167// NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument
168// with the given name, running a given callback, and customized with
169// options.  May return an error if the name is invalid (e.g., empty)
170// or improperly registered (e.g., duplicate registration).
171func (m Meter) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, opts ...InstrumentOption) (Int64UpDownSumObserver, error) {
172	if callback == nil {
173		return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
174	}
175	return wrapInt64UpDownSumObserverInstrument(
176		m.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts,
177			newInt64AsyncRunner(callback)))
178}
179
180// NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver with
181// the given name, running a given callback, and customized with
182// options.  May return an error if the name is invalid (e.g., empty)
183// or improperly registered (e.g., duplicate registration).
184func (m Meter) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, opts ...InstrumentOption) (Float64UpDownSumObserver, error) {
185	if callback == nil {
186		return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
187	}
188	return wrapFloat64UpDownSumObserverInstrument(
189		m.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts,
190			newFloat64AsyncRunner(callback)))
191}
192
193// NewInt64ValueObserver creates a new integer ValueObserver instrument
194// with the given name, running in a batch callback, and customized with
195// options.  May return an error if the name is invalid (e.g., empty)
196// or improperly registered (e.g., duplicate registration).
197func (b BatchObserver) NewInt64ValueObserver(name string, opts ...InstrumentOption) (Int64ValueObserver, error) {
198	if b.runner == nil {
199		return wrapInt64ValueObserverInstrument(NoopAsync{}, nil)
200	}
201	return wrapInt64ValueObserverInstrument(
202		b.meter.newAsync(name, ValueObserverInstrumentKind, number.Int64Kind, opts, b.runner))
203}
204
205// NewFloat64ValueObserver creates a new floating point ValueObserver with
206// the given name, running in a batch callback, and customized with
207// options.  May return an error if the name is invalid (e.g., empty)
208// or improperly registered (e.g., duplicate registration).
209func (b BatchObserver) NewFloat64ValueObserver(name string, opts ...InstrumentOption) (Float64ValueObserver, error) {
210	if b.runner == nil {
211		return wrapFloat64ValueObserverInstrument(NoopAsync{}, nil)
212	}
213	return wrapFloat64ValueObserverInstrument(
214		b.meter.newAsync(name, ValueObserverInstrumentKind, number.Float64Kind, opts,
215			b.runner))
216}
217
218// NewInt64SumObserver creates a new integer SumObserver instrument
219// with the given name, running in a batch callback, and customized with
220// options.  May return an error if the name is invalid (e.g., empty)
221// or improperly registered (e.g., duplicate registration).
222func (b BatchObserver) NewInt64SumObserver(name string, opts ...InstrumentOption) (Int64SumObserver, error) {
223	if b.runner == nil {
224		return wrapInt64SumObserverInstrument(NoopAsync{}, nil)
225	}
226	return wrapInt64SumObserverInstrument(
227		b.meter.newAsync(name, SumObserverInstrumentKind, number.Int64Kind, opts, b.runner))
228}
229
230// NewFloat64SumObserver creates a new floating point SumObserver with
231// the given name, running in a batch callback, and customized with
232// options.  May return an error if the name is invalid (e.g., empty)
233// or improperly registered (e.g., duplicate registration).
234func (b BatchObserver) NewFloat64SumObserver(name string, opts ...InstrumentOption) (Float64SumObserver, error) {
235	if b.runner == nil {
236		return wrapFloat64SumObserverInstrument(NoopAsync{}, nil)
237	}
238	return wrapFloat64SumObserverInstrument(
239		b.meter.newAsync(name, SumObserverInstrumentKind, number.Float64Kind, opts,
240			b.runner))
241}
242
243// NewInt64UpDownSumObserver creates a new integer UpDownSumObserver instrument
244// with the given name, running in a batch callback, and customized with
245// options.  May return an error if the name is invalid (e.g., empty)
246// or improperly registered (e.g., duplicate registration).
247func (b BatchObserver) NewInt64UpDownSumObserver(name string, opts ...InstrumentOption) (Int64UpDownSumObserver, error) {
248	if b.runner == nil {
249		return wrapInt64UpDownSumObserverInstrument(NoopAsync{}, nil)
250	}
251	return wrapInt64UpDownSumObserverInstrument(
252		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Int64Kind, opts, b.runner))
253}
254
255// NewFloat64UpDownSumObserver creates a new floating point UpDownSumObserver with
256// the given name, running in a batch callback, and customized with
257// options.  May return an error if the name is invalid (e.g., empty)
258// or improperly registered (e.g., duplicate registration).
259func (b BatchObserver) NewFloat64UpDownSumObserver(name string, opts ...InstrumentOption) (Float64UpDownSumObserver, error) {
260	if b.runner == nil {
261		return wrapFloat64UpDownSumObserverInstrument(NoopAsync{}, nil)
262	}
263	return wrapFloat64UpDownSumObserverInstrument(
264		b.meter.newAsync(name, UpDownSumObserverInstrumentKind, number.Float64Kind, opts,
265			b.runner))
266}
267
268// MeterImpl returns the underlying MeterImpl of this Meter.
269func (m Meter) MeterImpl() MeterImpl {
270	return m.impl
271}
272
273// newAsync constructs one new asynchronous instrument.
274func (m Meter) newAsync(
275	name string,
276	mkind InstrumentKind,
277	nkind number.Kind,
278	opts []InstrumentOption,
279	runner AsyncRunner,
280) (
281	AsyncImpl,
282	error,
283) {
284	if m.impl == nil {
285		return NoopAsync{}, nil
286	}
287	desc := NewDescriptor(name, mkind, nkind, opts...)
288	desc.config.InstrumentationName = m.name
289	desc.config.InstrumentationVersion = m.version
290	return m.impl.NewAsyncInstrument(desc, runner)
291}
292
293// newSync constructs one new synchronous instrument.
294func (m Meter) newSync(
295	name string,
296	metricKind InstrumentKind,
297	numberKind number.Kind,
298	opts []InstrumentOption,
299) (
300	SyncImpl,
301	error,
302) {
303	if m.impl == nil {
304		return NoopSync{}, nil
305	}
306	desc := NewDescriptor(name, metricKind, numberKind, opts...)
307	desc.config.InstrumentationName = m.name
308	desc.config.InstrumentationVersion = m.version
309	return m.impl.NewSyncInstrument(desc)
310}
311
312// MeterMust is a wrapper for Meter interfaces that panics when any
313// instrument constructor encounters an error.
314type MeterMust struct {
315	meter Meter
316}
317
318// BatchObserverMust is a wrapper for BatchObserver that panics when
319// any instrument constructor encounters an error.
320type BatchObserverMust struct {
321	batch BatchObserver
322}
323
324// Must constructs a MeterMust implementation from a Meter, allowing
325// the application to panic when any instrument constructor yields an
326// error.
327func Must(meter Meter) MeterMust {
328	return MeterMust{meter: meter}
329}
330
331// NewInt64Counter calls `Meter.NewInt64Counter` and returns the
332// instrument, panicking if it encounters an error.
333func (mm MeterMust) NewInt64Counter(name string, cos ...InstrumentOption) Int64Counter {
334	if inst, err := mm.meter.NewInt64Counter(name, cos...); err != nil {
335		panic(err)
336	} else {
337		return inst
338	}
339}
340
341// NewFloat64Counter calls `Meter.NewFloat64Counter` and returns the
342// instrument, panicking if it encounters an error.
343func (mm MeterMust) NewFloat64Counter(name string, cos ...InstrumentOption) Float64Counter {
344	if inst, err := mm.meter.NewFloat64Counter(name, cos...); err != nil {
345		panic(err)
346	} else {
347		return inst
348	}
349}
350
351// NewInt64UpDownCounter calls `Meter.NewInt64UpDownCounter` and returns the
352// instrument, panicking if it encounters an error.
353func (mm MeterMust) NewInt64UpDownCounter(name string, cos ...InstrumentOption) Int64UpDownCounter {
354	if inst, err := mm.meter.NewInt64UpDownCounter(name, cos...); err != nil {
355		panic(err)
356	} else {
357		return inst
358	}
359}
360
361// NewFloat64UpDownCounter calls `Meter.NewFloat64UpDownCounter` and returns the
362// instrument, panicking if it encounters an error.
363func (mm MeterMust) NewFloat64UpDownCounter(name string, cos ...InstrumentOption) Float64UpDownCounter {
364	if inst, err := mm.meter.NewFloat64UpDownCounter(name, cos...); err != nil {
365		panic(err)
366	} else {
367		return inst
368	}
369}
370
371// NewInt64ValueRecorder calls `Meter.NewInt64ValueRecorder` and returns the
372// instrument, panicking if it encounters an error.
373func (mm MeterMust) NewInt64ValueRecorder(name string, mos ...InstrumentOption) Int64ValueRecorder {
374	if inst, err := mm.meter.NewInt64ValueRecorder(name, mos...); err != nil {
375		panic(err)
376	} else {
377		return inst
378	}
379}
380
381// NewFloat64ValueRecorder calls `Meter.NewFloat64ValueRecorder` and returns the
382// instrument, panicking if it encounters an error.
383func (mm MeterMust) NewFloat64ValueRecorder(name string, mos ...InstrumentOption) Float64ValueRecorder {
384	if inst, err := mm.meter.NewFloat64ValueRecorder(name, mos...); err != nil {
385		panic(err)
386	} else {
387		return inst
388	}
389}
390
391// NewInt64ValueObserver calls `Meter.NewInt64ValueObserver` and
392// returns the instrument, panicking if it encounters an error.
393func (mm MeterMust) NewInt64ValueObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64ValueObserver {
394	if inst, err := mm.meter.NewInt64ValueObserver(name, callback, oos...); err != nil {
395		panic(err)
396	} else {
397		return inst
398	}
399}
400
401// NewFloat64ValueObserver calls `Meter.NewFloat64ValueObserver` and
402// returns the instrument, panicking if it encounters an error.
403func (mm MeterMust) NewFloat64ValueObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64ValueObserver {
404	if inst, err := mm.meter.NewFloat64ValueObserver(name, callback, oos...); err != nil {
405		panic(err)
406	} else {
407		return inst
408	}
409}
410
411// NewInt64SumObserver calls `Meter.NewInt64SumObserver` and
412// returns the instrument, panicking if it encounters an error.
413func (mm MeterMust) NewInt64SumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64SumObserver {
414	if inst, err := mm.meter.NewInt64SumObserver(name, callback, oos...); err != nil {
415		panic(err)
416	} else {
417		return inst
418	}
419}
420
421// NewFloat64SumObserver calls `Meter.NewFloat64SumObserver` and
422// returns the instrument, panicking if it encounters an error.
423func (mm MeterMust) NewFloat64SumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64SumObserver {
424	if inst, err := mm.meter.NewFloat64SumObserver(name, callback, oos...); err != nil {
425		panic(err)
426	} else {
427		return inst
428	}
429}
430
431// NewInt64UpDownSumObserver calls `Meter.NewInt64UpDownSumObserver` and
432// returns the instrument, panicking if it encounters an error.
433func (mm MeterMust) NewInt64UpDownSumObserver(name string, callback Int64ObserverFunc, oos ...InstrumentOption) Int64UpDownSumObserver {
434	if inst, err := mm.meter.NewInt64UpDownSumObserver(name, callback, oos...); err != nil {
435		panic(err)
436	} else {
437		return inst
438	}
439}
440
441// NewFloat64UpDownSumObserver calls `Meter.NewFloat64UpDownSumObserver` and
442// returns the instrument, panicking if it encounters an error.
443func (mm MeterMust) NewFloat64UpDownSumObserver(name string, callback Float64ObserverFunc, oos ...InstrumentOption) Float64UpDownSumObserver {
444	if inst, err := mm.meter.NewFloat64UpDownSumObserver(name, callback, oos...); err != nil {
445		panic(err)
446	} else {
447		return inst
448	}
449}
450
451// NewBatchObserver returns a wrapper around BatchObserver that panics
452// when any instrument constructor returns an error.
453func (mm MeterMust) NewBatchObserver(callback BatchObserverFunc) BatchObserverMust {
454	return BatchObserverMust{
455		batch: mm.meter.NewBatchObserver(callback),
456	}
457}
458
459// NewInt64ValueObserver calls `BatchObserver.NewInt64ValueObserver` and
460// returns the instrument, panicking if it encounters an error.
461func (bm BatchObserverMust) NewInt64ValueObserver(name string, oos ...InstrumentOption) Int64ValueObserver {
462	if inst, err := bm.batch.NewInt64ValueObserver(name, oos...); err != nil {
463		panic(err)
464	} else {
465		return inst
466	}
467}
468
469// NewFloat64ValueObserver calls `BatchObserver.NewFloat64ValueObserver` and
470// returns the instrument, panicking if it encounters an error.
471func (bm BatchObserverMust) NewFloat64ValueObserver(name string, oos ...InstrumentOption) Float64ValueObserver {
472	if inst, err := bm.batch.NewFloat64ValueObserver(name, oos...); err != nil {
473		panic(err)
474	} else {
475		return inst
476	}
477}
478
479// NewInt64SumObserver calls `BatchObserver.NewInt64SumObserver` and
480// returns the instrument, panicking if it encounters an error.
481func (bm BatchObserverMust) NewInt64SumObserver(name string, oos ...InstrumentOption) Int64SumObserver {
482	if inst, err := bm.batch.NewInt64SumObserver(name, oos...); err != nil {
483		panic(err)
484	} else {
485		return inst
486	}
487}
488
489// NewFloat64SumObserver calls `BatchObserver.NewFloat64SumObserver` and
490// returns the instrument, panicking if it encounters an error.
491func (bm BatchObserverMust) NewFloat64SumObserver(name string, oos ...InstrumentOption) Float64SumObserver {
492	if inst, err := bm.batch.NewFloat64SumObserver(name, oos...); err != nil {
493		panic(err)
494	} else {
495		return inst
496	}
497}
498
499// NewInt64UpDownSumObserver calls `BatchObserver.NewInt64UpDownSumObserver` and
500// returns the instrument, panicking if it encounters an error.
501func (bm BatchObserverMust) NewInt64UpDownSumObserver(name string, oos ...InstrumentOption) Int64UpDownSumObserver {
502	if inst, err := bm.batch.NewInt64UpDownSumObserver(name, oos...); err != nil {
503		panic(err)
504	} else {
505		return inst
506	}
507}
508
509// NewFloat64UpDownSumObserver calls `BatchObserver.NewFloat64UpDownSumObserver` and
510// returns the instrument, panicking if it encounters an error.
511func (bm BatchObserverMust) NewFloat64UpDownSumObserver(name string, oos ...InstrumentOption) Float64UpDownSumObserver {
512	if inst, err := bm.batch.NewFloat64UpDownSumObserver(name, oos...); err != nil {
513		panic(err)
514	} else {
515		return inst
516	}
517}
518
519// Descriptor contains all the settings that describe an instrument,
520// including its name, metric kind, number kind, and the configurable
521// options.
522type Descriptor struct {
523	name           string
524	instrumentKind InstrumentKind
525	numberKind     number.Kind
526	config         InstrumentConfig
527}
528
529// NewDescriptor returns a Descriptor with the given contents.
530func NewDescriptor(name string, ikind InstrumentKind, nkind number.Kind, opts ...InstrumentOption) Descriptor {
531	return Descriptor{
532		name:           name,
533		instrumentKind: ikind,
534		numberKind:     nkind,
535		config:         NewInstrumentConfig(opts...),
536	}
537}
538
539// Name returns the metric instrument's name.
540func (d Descriptor) Name() string {
541	return d.name
542}
543
544// InstrumentKind returns the specific kind of instrument.
545func (d Descriptor) InstrumentKind() InstrumentKind {
546	return d.instrumentKind
547}
548
549// Description provides a human-readable description of the metric
550// instrument.
551func (d Descriptor) Description() string {
552	return d.config.Description
553}
554
555// Unit describes the units of the metric instrument.  Unitless
556// metrics return the empty string.
557func (d Descriptor) Unit() unit.Unit {
558	return d.config.Unit
559}
560
561// NumberKind returns whether this instrument is declared over int64,
562// float64, or uint64 values.
563func (d Descriptor) NumberKind() number.Kind {
564	return d.numberKind
565}
566
567// InstrumentationName returns the name of the library that provided
568// instrumentation for this instrument.
569func (d Descriptor) InstrumentationName() string {
570	return d.config.InstrumentationName
571}
572
573// InstrumentationVersion returns the version of the library that provided
574// instrumentation for this instrument.
575func (d Descriptor) InstrumentationVersion() string {
576	return d.config.InstrumentationVersion
577}
578