LCOV - code coverage report
Current view: top level - src/metrics - meter.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 92.9 % 127 118
Test Date: 2025-11-15 13:23:01 Functions: - 0 0

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

Generated by: LCOV version 2.0-1