Line data Source code
1 : // Copyright The OpenTelemetry Authors
2 : // SPDX-License-Identifier: Apache-2.0
3 :
4 : import 'package:dartastic_opentelemetry_api/dartastic_opentelemetry_api.dart';
5 : import 'package:meta/meta.dart';
6 :
7 : import 'instruments/counter.dart';
8 : import 'instruments/gauge.dart';
9 : import 'instruments/histogram.dart';
10 : import 'instruments/observable_counter.dart';
11 : import 'instruments/observable_gauge.dart';
12 : import 'instruments/observable_up_down_counter.dart';
13 : import 'instruments/up_down_counter.dart';
14 : import 'meter_provider.dart';
15 :
16 : part 'meter_create.dart';
17 :
18 : /// SDK implementation of the APIMeter interface.
19 : ///
20 : /// A Meter is the entry point for creating instruments that collect measurements for a specific
21 : /// instrumentation scope. Meters are obtained from a MeterProvider, and each Meter is associated
22 : /// with a specific instrumentation library, version, and optional schema URL.
23 : ///
24 : /// The Meter follows the OpenTelemetry metrics data model which consists of instruments that
25 : /// record measurements, which are then aggregated into metrics. This implementation delegates
26 : /// to the API implementation while adding SDK-specific behaviors.
27 : ///
28 : /// More information:
29 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/
30 : /// https://opentelemetry.io/docs/specs/otel/metrics/sdk/
31 : class Meter implements APIMeter {
32 : /// The underlying API Meter implementation.
33 : final APIMeter _delegate;
34 :
35 : /// The MeterProvider that created this Meter.
36 : final MeterProvider _provider;
37 :
38 : /// Private constructor for creating Meter instances.
39 : ///
40 : /// @param delegate The API Meter implementation to delegate to
41 : /// @param provider The MeterProvider that created this Meter
42 28 : Meter._({required APIMeter delegate, required MeterProvider provider})
43 : : _delegate = delegate,
44 : _provider = provider;
45 :
46 : /// Gets the name of the instrumentation scope.
47 : ///
48 : /// This name uniquely identifies the instrumentation library, such as
49 : /// the package, module, or class name.
50 27 : @override
51 54 : String get name => _delegate.name;
52 :
53 : /// Gets the version of the instrumentation scope.
54 : ///
55 : /// This represents the version of the instrumentation library.
56 1 : @override
57 2 : String? get version => _delegate.version;
58 :
59 : /// Gets the schema URL of the instrumentation scope.
60 : ///
61 : /// This URL identifies the schema that defines the instrumentation scope.
62 1 : @override
63 2 : String? get schemaUrl => _delegate.schemaUrl;
64 :
65 : /// Gets the attributes associated with this meter.
66 : ///
67 : /// These attributes provide additional context about the instrumentation scope.
68 1 : @override
69 2 : Attributes? get attributes => _delegate.attributes;
70 :
71 : /// Indicates whether this meter is enabled.
72 : ///
73 : /// If false, instruments created by this meter will not record measurements.
74 : /// This is controlled by the associated MeterProvider.
75 19 : @override
76 38 : bool get enabled => _provider.enabled;
77 :
78 : /// Gets the MeterProvider that created this Meter.
79 : ///
80 : /// @return The MeterProvider instance
81 50 : MeterProvider get provider => _provider;
82 :
83 : /// Creates a Counter instrument for recording cumulative, monotonically increasing values.
84 : ///
85 : /// Counters are used to measure a non-negative, monotonically increasing value. They only
86 : /// allow positive increments and are appropriate for values that never decrease, such as
87 : /// request counts, completed operations, or error counts.
88 : ///
89 : /// @param name The name of the instrument, which should be unique within the meter
90 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "requests")
91 : /// @param description Optional description of what the instrument measures
92 : /// @return A Counter instrument of the specified numeric type
93 : ///
94 : /// More information:
95 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#counter
96 12 : @override
97 : APICounter<T> createCounter<T extends num>({
98 : required String name,
99 : String? unit,
100 : String? description,
101 : }) {
102 : // First call the API implementation to get the API object
103 24 : final apiCounter = _delegate.createCounter<T>(
104 : name: name,
105 : unit: unit,
106 : description: description,
107 : );
108 :
109 : // Now wrap it with our SDK implementation
110 12 : return Counter<T>(apiCounter: apiCounter, meter: this);
111 : }
112 :
113 : /// Creates an UpDownCounter instrument for recording cumulative values that can increase or decrease.
114 : ///
115 : /// UpDownCounters are used to measure values that can go up or down over time. They are appropriate
116 : /// for values that represent a current state, such as active requests, queue size, or resource usage.
117 : ///
118 : /// @param name The name of the instrument, which should be unique within the meter
119 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "requests")
120 : /// @param description Optional description of what the instrument measures
121 : /// @return An UpDownCounter instrument of the specified numeric type
122 : ///
123 : /// More information:
124 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#updowncounter
125 5 : @override
126 : APIUpDownCounter<T> createUpDownCounter<T extends num>({
127 : required String name,
128 : String? unit,
129 : String? description,
130 : }) {
131 : // First call the API implementation to get the API object
132 10 : final apiCounter = _delegate.createUpDownCounter<T>(
133 : name: name,
134 : unit: unit,
135 : description: description,
136 : );
137 :
138 : // Now wrap it with our SDK implementation
139 5 : return UpDownCounter<T>(apiCounter: apiCounter, meter: this);
140 : }
141 :
142 : /// Creates a Histogram instrument for recording a distribution of values.
143 : ///
144 : /// Histograms are used to measure the distribution of values, such as request durations or
145 : /// response sizes. They provide statistics about the distribution, including count, sum,
146 : /// min, max, and quantiles.
147 : ///
148 : /// @param name The name of the instrument, which should be unique within the meter
149 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes")
150 : /// @param description Optional description of what the instrument measures
151 : /// @param boundaries Optional explicit histogram bucket boundaries in increasing order
152 : /// @return A Histogram instrument of the specified numeric type
153 : ///
154 : /// More information:
155 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#histogram
156 7 : @override
157 : APIHistogram<T> createHistogram<T extends num>({
158 : required String name,
159 : String? unit,
160 : String? description,
161 : List<double>? boundaries,
162 : }) {
163 : // First call the API implementation to get the API object
164 14 : final apiHistogram = _delegate.createHistogram<T>(
165 : name: name,
166 : unit: unit,
167 : description: description,
168 : boundaries: boundaries,
169 : );
170 :
171 : // Now wrap it with our SDK implementation
172 7 : return Histogram<T>(
173 : apiHistogram: apiHistogram,
174 : meter: this,
175 : boundaries: boundaries,
176 : );
177 : }
178 :
179 : /// Creates a Gauge instrument for recording the current value at the time of measurement.
180 : ///
181 : /// Gauges are used to measure the instantaneous value of something, such as the current
182 : /// CPU usage, memory usage, or temperature. They report the most recently observed value.
183 : ///
184 : /// @param name The name of the instrument, which should be unique within the meter
185 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "percent")
186 : /// @param description Optional description of what the instrument measures
187 : /// @return A Gauge instrument of the specified numeric type
188 : ///
189 : /// More information:
190 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#gauge
191 6 : @override
192 : APIGauge<T> createGauge<T extends num>({
193 : required String name,
194 : String? unit,
195 : String? description,
196 : }) {
197 : // First call the API implementation to get the API object
198 12 : final apiGauge = _delegate.createGauge<T>(
199 : name: name,
200 : unit: unit,
201 : description: description,
202 : );
203 :
204 : // Now wrap it with our SDK implementation
205 6 : return Gauge<T>(apiGauge: apiGauge, meter: this);
206 : }
207 :
208 : /// Creates an ObservableCounter instrument for asynchronously recording cumulative, monotonically increasing values.
209 : ///
210 : /// ObservableCounters are used when measurements are expensive to compute and should be
211 : /// collected only when needed, or when they come from an external source. They are appropriate
212 : /// for the same use cases as Counters, but with asynchronous collection.
213 : ///
214 : /// @param name The name of the instrument, which should be unique within the meter
215 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "requests")
216 : /// @param description Optional description of what the instrument measures
217 : /// @param callback Optional callback function that will be called when measurements are collected
218 : /// @return An ObservableCounter instrument of the specified numeric type
219 : ///
220 : /// More information:
221 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#asynchronous-counter
222 10 : @override
223 : APIObservableCounter<T> createObservableCounter<T extends num>({
224 : required String name,
225 : String? unit,
226 : String? description,
227 : ObservableCallback<T>? callback,
228 : }) {
229 : // First call the API implementation to get the API object
230 20 : final apiCounter = _delegate.createObservableCounter<T>(
231 : name: name,
232 : unit: unit,
233 : description: description,
234 : callback: callback,
235 : );
236 :
237 : // Now wrap it with our SDK implementation
238 10 : final counter = ObservableCounter<T>(apiCounter: apiCounter, meter: this);
239 :
240 : // Register the instrument with the meter provider
241 20 : _provider.registerInstrument(name, counter);
242 :
243 : return counter;
244 : }
245 :
246 : /// Creates an ObservableUpDownCounter instrument for asynchronously recording cumulative values that can increase or decrease.
247 : ///
248 : /// ObservableUpDownCounters are used when measurements are expensive to compute and should be
249 : /// collected only when needed, or when they come from an external source. They are appropriate
250 : /// for the same use cases as UpDownCounters, but with asynchronous collection.
251 : ///
252 : /// @param name The name of the instrument, which should be unique within the meter
253 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "requests")
254 : /// @param description Optional description of what the instrument measures
255 : /// @param callback Optional callback function that will be called when measurements are collected
256 : /// @return An ObservableUpDownCounter instrument of the specified numeric type
257 : ///
258 : /// More information:
259 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#asynchronous-updowncounter
260 7 : @override
261 : APIObservableUpDownCounter<T> createObservableUpDownCounter<T extends num>({
262 : required String name,
263 : String? unit,
264 : String? description,
265 : ObservableCallback<T>? callback,
266 : }) {
267 : // First call the API implementation to get the API object
268 14 : final apiCounter = _delegate.createObservableUpDownCounter<T>(
269 : name: name,
270 : unit: unit,
271 : description: description,
272 : callback: callback,
273 : );
274 :
275 : // Now wrap it with our SDK implementation
276 7 : final counter = ObservableUpDownCounter<T>(
277 : apiCounter: apiCounter,
278 : meter: this,
279 : );
280 :
281 : // Register the instrument with the meter provider
282 14 : _provider.registerInstrument(name, counter);
283 :
284 : return counter;
285 : }
286 :
287 : /// Creates an ObservableGauge instrument for asynchronously recording the current value at collection time.
288 : ///
289 : /// ObservableGauges are used when measurements are expensive to compute and should be
290 : /// collected only when needed, or when they come from an external source. They are appropriate
291 : /// for the same use cases as Gauges, but with asynchronous collection.
292 : ///
293 : /// @param name The name of the instrument, which should be unique within the meter
294 : /// @param unit Optional unit of measurement (e.g., "ms", "bytes", "percent")
295 : /// @param description Optional description of what the instrument measures
296 : /// @param callback Optional callback function that will be called when measurements are collected
297 : /// @return An ObservableGauge instrument of the specified numeric type
298 : ///
299 : /// More information:
300 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#asynchronous-gauge
301 7 : @override
302 : APIObservableGauge<T> createObservableGauge<T extends num>({
303 : required String name,
304 : String? unit,
305 : String? description,
306 : ObservableCallback<T>? callback,
307 : }) {
308 : // First call the API implementation to get the API object
309 14 : final apiGauge = _delegate.createObservableGauge<T>(
310 : name: name,
311 : unit: unit,
312 : description: description,
313 : callback: callback,
314 : );
315 :
316 : // Now wrap it with our SDK implementation
317 7 : final gauge = ObservableGauge<T>(apiGauge: apiGauge, meter: this);
318 :
319 : // Register the instrument with the meter provider
320 14 : _provider.registerInstrument(name, gauge);
321 :
322 : return gauge;
323 : }
324 : }
325 :
326 : /// A no-op implementation of Meter that doesn't record any metrics.
327 : ///
328 : /// This implementation is used when the MeterProvider has been shut down
329 : /// or if metrics collection is disabled. It provides the same interface as
330 : /// a regular Meter but does nothing when measurements are recorded.
331 : ///
332 : /// More information:
333 : /// https://opentelemetry.io/docs/specs/otel/metrics/api/#no-op-implementations
334 : class NoopMeter implements APIMeter {
335 : @override
336 : final String name;
337 :
338 : @override
339 : final String? version;
340 :
341 : @override
342 : final String? schemaUrl;
343 :
344 : @override
345 : final Attributes? attributes = null;
346 :
347 : @override
348 : final bool enabled = false;
349 :
350 : /// Creates a new NoopMeter with the specified name and optional version and schema URL.
351 : ///
352 : /// @param name The name of the instrumentation scope
353 : /// @param version Optional version of the instrumentation scope
354 : /// @param schemaUrl Optional URL of the schema defining the instrumentation scope
355 3 : NoopMeter({required this.name, this.version, this.schemaUrl});
356 :
357 1 : @override
358 : APICounter<T> createCounter<T extends num>({
359 : required String name,
360 : String? unit,
361 : String? description,
362 : }) {
363 1 : return NoopCounter<T>(name: name, unit: unit, description: description);
364 : }
365 :
366 1 : @override
367 : APIUpDownCounter<T> createUpDownCounter<T extends num>({
368 : required String name,
369 : String? unit,
370 : String? description,
371 : }) {
372 1 : return NoopUpDownCounter<T>(
373 : name: name,
374 : unit: unit,
375 : description: description,
376 : );
377 : }
378 :
379 1 : @override
380 : APIHistogram<T> createHistogram<T extends num>({
381 : required String name,
382 : String? unit,
383 : String? description,
384 : List<double>? boundaries,
385 : }) {
386 1 : return NoopHistogram<T>(
387 : name: name,
388 : unit: unit,
389 : description: description,
390 : boundaries: boundaries,
391 : );
392 : }
393 :
394 1 : @override
395 : APIGauge<T> createGauge<T extends num>({
396 : required String name,
397 : String? unit,
398 : String? description,
399 : }) {
400 1 : return NoopGauge<T>(name: name, unit: unit, description: description);
401 : }
402 :
403 1 : @override
404 : APIObservableCounter<T> createObservableCounter<T extends num>({
405 : required String name,
406 : String? unit,
407 : String? description,
408 : ObservableCallback<T>? callback,
409 : }) {
410 1 : return NoopObservableCounter<T>(
411 : name: name,
412 : unit: unit,
413 : description: description,
414 : callback: callback,
415 : );
416 : }
417 :
418 1 : @override
419 : APIObservableUpDownCounter<T> createObservableUpDownCounter<T extends num>({
420 : required String name,
421 : String? unit,
422 : String? description,
423 : ObservableCallback<T>? callback,
424 : }) {
425 1 : return NoopObservableUpDownCounter<T>(
426 : name: name,
427 : unit: unit,
428 : description: description,
429 : callback: callback,
430 : );
431 : }
432 :
433 1 : @override
434 : APIObservableGauge<T> createObservableGauge<T extends num>({
435 : required String name,
436 : String? unit,
437 : String? description,
438 : ObservableCallback<T>? callback,
439 : }) {
440 1 : return NoopObservableGauge<T>(
441 : name: name,
442 : unit: unit,
443 : description: description,
444 : callback: callback,
445 : );
446 : }
447 : }
448 :
449 : /// No-op implementation of Counter instrument.
450 : ///
451 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
452 : /// maintaining the same interface as a functional Counter but performing no operations.
453 : class NoopCounter<T extends num> implements APICounter<T> {
454 : @override
455 : final String name;
456 :
457 : @override
458 : final String? description;
459 :
460 : @override
461 : final String? unit;
462 :
463 : @override
464 : final bool enabled = false;
465 :
466 : @override
467 : final APIMeter meter;
468 :
469 : /// Creates a new NoopCounter with the specified name, unit, and description.
470 : ///
471 : /// @param name The name of the instrument
472 : /// @param unit Optional unit of measurement
473 : /// @param description Optional description of what the instrument measures
474 1 : NoopCounter({required this.name, this.unit, this.description})
475 1 : : meter = NoopMeter(name: 'noop-meter');
476 :
477 : /// Records a measurement (no-op implementation).
478 : ///
479 : /// @param value The measurement value (ignored)
480 : /// @param attributes Optional attributes to associate with the measurement (ignored)
481 1 : @override
482 : void add(T value, [Attributes? attributes]) {
483 : // No-op
484 : }
485 :
486 : /// Records a measurement with attributes as a map (no-op implementation).
487 : ///
488 : /// @param value The measurement value (ignored)
489 : /// @param attributeMap Map of attribute names to values (ignored)
490 1 : @override
491 : void addWithMap(T value, Map<String, Object> attributeMap) {
492 : // No-op
493 : }
494 :
495 1 : @override
496 : bool get isCounter => true;
497 :
498 1 : @override
499 : bool get isGauge => false;
500 :
501 1 : @override
502 : bool get isHistogram => false;
503 :
504 1 : @override
505 : bool get isUpDownCounter => false;
506 : }
507 :
508 : /// No-op implementation of UpDownCounter instrument.
509 : ///
510 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
511 : /// maintaining the same interface as a functional UpDownCounter but performing no operations.
512 : class NoopUpDownCounter<T extends num> implements APIUpDownCounter<T> {
513 : @override
514 : final String name;
515 :
516 : @override
517 : final String? description;
518 :
519 : @override
520 : final String? unit;
521 :
522 : @override
523 : final bool enabled = false;
524 :
525 : @override
526 : final APIMeter meter;
527 :
528 : /// Creates a new NoopUpDownCounter with the specified name, unit, and description.
529 : ///
530 : /// @param name The name of the instrument
531 : /// @param unit Optional unit of measurement
532 : /// @param description Optional description of what the instrument measures
533 1 : NoopUpDownCounter({required this.name, this.unit, this.description})
534 1 : : meter = NoopMeter(name: 'noop-meter');
535 :
536 : /// Records a measurement (no-op implementation).
537 : ///
538 : /// @param value The measurement value (ignored)
539 : /// @param attributes Optional attributes to associate with the measurement (ignored)
540 1 : @override
541 : void add(T value, [Attributes? attributes]) {
542 : // No-op
543 : }
544 :
545 : /// Records a measurement with attributes as a map (no-op implementation).
546 : ///
547 : /// @param value The measurement value (ignored)
548 : /// @param attributeMap Map of attribute names to values (ignored)
549 1 : @override
550 : void addWithMap(T value, Map<String, Object> attributeMap) {
551 : // No-op
552 : }
553 :
554 1 : @override
555 : bool get isCounter => false;
556 :
557 1 : @override
558 : bool get isGauge => false;
559 :
560 1 : @override
561 : bool get isHistogram => false;
562 :
563 1 : @override
564 : bool get isUpDownCounter => true;
565 : }
566 :
567 : /// No-op implementation of Histogram instrument.
568 : ///
569 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
570 : /// maintaining the same interface as a functional Histogram but performing no operations.
571 : class NoopHistogram<T extends num> implements APIHistogram<T> {
572 : @override
573 : final String name;
574 :
575 : @override
576 : final String? description;
577 :
578 : @override
579 : final String? unit;
580 :
581 : @override
582 : final List<double>? boundaries;
583 :
584 : @override
585 : final bool enabled = false;
586 :
587 : @override
588 : final APIMeter meter;
589 :
590 : /// Creates a new NoopHistogram with the specified name, unit, description, and boundaries.
591 : ///
592 : /// @param name The name of the instrument
593 : /// @param unit Optional unit of measurement
594 : /// @param description Optional description of what the instrument measures
595 : /// @param boundaries Optional explicit histogram bucket boundaries
596 1 : NoopHistogram({
597 : required this.name,
598 : this.unit,
599 : this.description,
600 : this.boundaries,
601 1 : }) : meter = NoopMeter(name: 'noop-meter');
602 :
603 : /// Records a measurement (no-op implementation).
604 : ///
605 : /// @param value The measurement value (ignored)
606 : /// @param attributes Optional attributes to associate with the measurement (ignored)
607 1 : @override
608 : void record(T value, [Attributes? attributes]) {
609 : // No-op
610 : }
611 :
612 : /// Records a measurement with attributes as a map (no-op implementation).
613 : ///
614 : /// @param value The measurement value (ignored)
615 : /// @param attributeMap Map of attribute names to values (ignored)
616 1 : @override
617 : void recordWithMap(T value, Map<String, Object> attributeMap) {
618 : // No-op
619 : }
620 :
621 1 : @override
622 : bool get isCounter => false;
623 :
624 1 : @override
625 : bool get isGauge => false;
626 :
627 1 : @override
628 : bool get isHistogram => true;
629 :
630 1 : @override
631 : bool get isUpDownCounter => false;
632 : }
633 :
634 : /// No-op implementation of Gauge instrument.
635 : ///
636 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
637 : /// maintaining the same interface as a functional Gauge but performing no operations.
638 : class NoopGauge<T extends num> implements APIGauge<T> {
639 : @override
640 : final String name;
641 :
642 : @override
643 : final String? description;
644 :
645 : @override
646 : final String? unit;
647 :
648 : @override
649 : final bool enabled = false;
650 :
651 : @override
652 : final APIMeter meter;
653 :
654 : /// Creates a new NoopGauge with the specified name, unit, and description.
655 : ///
656 : /// @param name The name of the instrument
657 : /// @param unit Optional unit of measurement
658 : /// @param description Optional description of what the instrument measures
659 1 : NoopGauge({required this.name, this.unit, this.description})
660 1 : : meter = NoopMeter(name: 'noop-meter');
661 :
662 : /// Records a measurement (no-op implementation).
663 : ///
664 : /// @param value The measurement value (ignored)
665 : /// @param attributes Optional attributes to associate with the measurement (ignored)
666 1 : @override
667 : void record(T value, [Attributes? attributes]) {
668 : // No-op
669 : }
670 :
671 : /// Records a measurement with attributes as a map (no-op implementation).
672 : ///
673 : /// @param value The measurement value (ignored)
674 : /// @param attributeMap Map of attribute names to values (ignored)
675 1 : @override
676 : void recordWithMap(T value, Map<String, Object> attributeMap) {
677 : // No-op
678 : }
679 :
680 1 : @override
681 : bool get isCounter => false;
682 :
683 1 : @override
684 : bool get isGauge => true;
685 :
686 1 : @override
687 : bool get isHistogram => false;
688 :
689 1 : @override
690 : bool get isUpDownCounter => false;
691 : }
692 :
693 : /// No-op implementation of ObservableCounter instrument.
694 : ///
695 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
696 : /// maintaining the same interface as a functional ObservableCounter but performing no operations.
697 : class NoopObservableCounter<T extends num> implements APIObservableCounter<T> {
698 : @override
699 : final String name;
700 :
701 : @override
702 : final String? description;
703 :
704 : @override
705 : final String? unit;
706 :
707 : @override
708 : final bool enabled = false;
709 :
710 : @override
711 : final APIMeter meter;
712 :
713 : final List<ObservableCallback<T>> _callbacks = [];
714 :
715 : /// Creates a new NoopObservableCounter with the specified name, unit, description, and callback.
716 : ///
717 : /// @param name The name of the instrument
718 : /// @param unit Optional unit of measurement
719 : /// @param description Optional description of what the instrument measures
720 : /// @param callback Optional callback function that will be called when measurements are collected
721 2 : NoopObservableCounter({
722 : required this.name,
723 : this.unit,
724 : this.description,
725 : ObservableCallback<T>? callback,
726 2 : }) : meter = NoopMeter(name: 'noop-meter') {
727 : if (callback != null) {
728 0 : addCallback(callback);
729 : }
730 : }
731 :
732 : /// Gets all registered callbacks.
733 : ///
734 : /// @return An unmodifiable list of registered callbacks
735 1 : @override
736 2 : List<ObservableCallback<T>> get callbacks => List.unmodifiable(_callbacks);
737 :
738 : /// Registers a callback function for collecting measurements.
739 : ///
740 : /// @param callback The callback function to register
741 : /// @return A registration object that can be used to unregister the callback
742 1 : @override
743 : APICallbackRegistration<T> addCallback(ObservableCallback<T> callback) {
744 2 : _callbacks.add(callback);
745 1 : return _NoopCallbackRegistration<T>(this, callback);
746 : }
747 :
748 : /// Unregisters a previously registered callback function.
749 : ///
750 : /// @param callback The callback function to unregister
751 1 : @override
752 : void removeCallback(ObservableCallback<T> callback) {
753 2 : _callbacks.remove(callback);
754 : }
755 :
756 : /// Collects measurements from all registered callbacks (no-op implementation).
757 : ///
758 : /// @return An empty list of measurements
759 2 : @override
760 : List<Measurement> collect() {
761 2 : return <Measurement>[];
762 : }
763 : }
764 :
765 : /// No-op implementation of ObservableUpDownCounter instrument.
766 : ///
767 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
768 : /// maintaining the same interface as a functional ObservableUpDownCounter but performing no operations.
769 : class NoopObservableUpDownCounter<T extends num>
770 : implements APIObservableUpDownCounter<T> {
771 : @override
772 : final String name;
773 :
774 : @override
775 : final String? description;
776 :
777 : @override
778 : final String? unit;
779 :
780 : @override
781 : final bool enabled = false;
782 :
783 : @override
784 : final APIMeter meter;
785 :
786 : final List<ObservableCallback<T>> _callbacks = [];
787 :
788 : /// Creates a new NoopObservableUpDownCounter with the specified name, unit, description, and callback.
789 : ///
790 : /// @param name The name of the instrument
791 : /// @param unit Optional unit of measurement
792 : /// @param description Optional description of what the instrument measures
793 : /// @param callback Optional callback function that will be called when measurements are collected
794 2 : NoopObservableUpDownCounter({
795 : required this.name,
796 : this.unit,
797 : this.description,
798 : ObservableCallback<T>? callback,
799 2 : }) : meter = NoopMeter(name: 'noop-meter') {
800 : if (callback != null) {
801 0 : addCallback(callback);
802 : }
803 : }
804 :
805 : /// Gets all registered callbacks.
806 : ///
807 : /// @return An unmodifiable list of registered callbacks
808 1 : @override
809 2 : List<ObservableCallback<T>> get callbacks => List.unmodifiable(_callbacks);
810 :
811 : /// Registers a callback function for collecting measurements.
812 : ///
813 : /// @param callback The callback function to register
814 : /// @return A registration object that can be used to unregister the callback
815 1 : @override
816 : APICallbackRegistration<T> addCallback(ObservableCallback<T> callback) {
817 2 : _callbacks.add(callback);
818 1 : return _NoopCallbackRegistration<T>(this, callback);
819 : }
820 :
821 : /// Unregisters a previously registered callback function.
822 : ///
823 : /// @param callback The callback function to unregister
824 1 : @override
825 : void removeCallback(ObservableCallback<T> callback) {
826 2 : _callbacks.remove(callback);
827 : }
828 :
829 : /// Collects measurements from all registered callbacks (no-op implementation).
830 : ///
831 : /// @return An empty list of measurements
832 2 : @override
833 : List<Measurement> collect() {
834 2 : return <Measurement>[];
835 : }
836 : }
837 :
838 : /// No-op implementation of ObservableGauge instrument.
839 : ///
840 : /// This implementation conforms to the OpenTelemetry specification for no-op implementations,
841 : /// maintaining the same interface as a functional ObservableGauge but performing no operations.
842 : class NoopObservableGauge<T extends num> implements APIObservableGauge<T> {
843 : @override
844 : final String name;
845 :
846 : @override
847 : final String? description;
848 :
849 : @override
850 : final String? unit;
851 :
852 : @override
853 : final bool enabled = false;
854 :
855 : @override
856 : final APIMeter meter;
857 :
858 : final List<ObservableCallback<T>> _callbacks = [];
859 :
860 : /// Creates a new NoopObservableGauge with the specified name, unit, description, and callback.
861 : ///
862 : /// @param name The name of the instrument
863 : /// @param unit Optional unit of measurement
864 : /// @param description Optional description of what the instrument measures
865 : /// @param callback Optional callback function that will be called when measurements are collected
866 2 : NoopObservableGauge({
867 : required this.name,
868 : this.unit,
869 : this.description,
870 : ObservableCallback<T>? callback,
871 2 : }) : meter = NoopMeter(name: 'noop-meter') {
872 : if (callback != null) {
873 0 : addCallback(callback);
874 : }
875 : }
876 :
877 : /// Gets all registered callbacks.
878 : ///
879 : /// @return An unmodifiable list of registered callbacks
880 1 : @override
881 2 : List<ObservableCallback<T>> get callbacks => List.unmodifiable(_callbacks);
882 :
883 : /// Registers a callback function for collecting measurements.
884 : ///
885 : /// @param callback The callback function to register
886 : /// @return A registration object that can be used to unregister the callback
887 1 : @override
888 : APICallbackRegistration<T> addCallback(ObservableCallback<T> callback) {
889 2 : _callbacks.add(callback);
890 1 : return _NoopCallbackRegistration<T>(this, callback);
891 : }
892 :
893 : /// Unregisters a previously registered callback function.
894 : ///
895 : /// @param callback The callback function to unregister
896 1 : @override
897 : void removeCallback(ObservableCallback<T> callback) {
898 2 : _callbacks.remove(callback);
899 : }
900 :
901 : /// Collects measurements from all registered callbacks (no-op implementation).
902 : ///
903 : /// @return An empty list of measurements
904 2 : @override
905 : List<Measurement> collect() {
906 2 : return <Measurement>[];
907 : }
908 : }
909 :
910 : /// No-op implementation of callback registration for observable instruments.
911 : ///
912 : /// This implementation allows unregistering callbacks from no-op instruments.
913 : class _NoopCallbackRegistration<T extends num>
914 : implements APICallbackRegistration<T> {
915 : final dynamic _instrument;
916 : final ObservableCallback<T> _callback;
917 :
918 : /// Creates a new NoopCallbackRegistration.
919 : ///
920 : /// @param instrument The instrument that owns the callback
921 : /// @param callback The callback function to be unregistered
922 1 : _NoopCallbackRegistration(this._instrument, this._callback);
923 :
924 : /// Unregisters the callback from the instrument.
925 1 : @override
926 : void unregister() {
927 2 : if (_instrument is APIObservableCounter<T>) {
928 3 : (_instrument as APIObservableCounter<T>).removeCallback(_callback);
929 2 : } else if (_instrument is APIObservableUpDownCounter<T>) {
930 3 : (_instrument as APIObservableUpDownCounter<T>).removeCallback(_callback);
931 2 : } else if (_instrument is APIObservableGauge<T>) {
932 3 : (_instrument as APIObservableGauge<T>).removeCallback(_callback);
933 : }
934 : }
935 : }
|