LCOV - code coverage report
Current view: top level - src/metrics/instruments - histogram.dart (source / functions) Coverage Total Hit
Test: lcov.info Lines: 95.1 % 41 39
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 '../data/metric.dart';
       7              : import '../data/metric_point.dart';
       8              : import '../meter.dart';
       9              : import '../storage/histogram_storage.dart';
      10              : import 'base_instrument.dart';
      11              : 
      12              : /// Histogram is a synchronous instrument that records a distribution of values.
      13              : ///
      14              : /// A Histogram is used to measure a distribution of values, such as request durations,
      15              : /// response sizes, or latencies.
      16              : class Histogram<T extends num> implements APIHistogram<T>, SDKInstrument {
      17              :   /// The underlying API Histogram.
      18              :   final APIHistogram<T> _apiHistogram;
      19              : 
      20              :   /// The Meter that created this Histogram.
      21              :   final Meter _meter;
      22              : 
      23              :   /// Storage for accumulating histogram measurements.
      24              :   final HistogramStorage<T> _storage;
      25              : 
      26              :   /// Creates a new Histogram instance.
      27            4 :   Histogram({
      28              :     required APIHistogram<T> apiHistogram,
      29              :     required Meter meter,
      30              :     List<double>? boundaries,
      31              :   })  : _apiHistogram = apiHistogram,
      32              :         _meter = meter,
      33            4 :         _storage = HistogramStorage(
      34              :           boundaries: boundaries ?? _defaultBoundaries,
      35              :           recordMinMax: true,
      36              :         ) {
      37              :     // Register this instrument with the meter provider
      38           20 :     _meter.provider.registerInstrument(_meter.name, this);
      39              :   }
      40              : 
      41              :   /// Default bucket boundaries.
      42              :   static const List<double> _defaultBoundaries = [
      43              :     0,
      44              :     5,
      45              :     10,
      46              :     25,
      47              :     50,
      48              :     75,
      49              :     100,
      50              :     250,
      51              :     500,
      52              :     750,
      53              :     1000,
      54              :     2500,
      55              :     5000,
      56              :     7500,
      57              :     10000
      58              :   ];
      59              : 
      60            4 :   @override
      61            8 :   String get name => _apiHistogram.name;
      62              : 
      63            3 :   @override
      64            6 :   String? get unit => _apiHistogram.unit;
      65              : 
      66            3 :   @override
      67            6 :   String? get description => _apiHistogram.description;
      68              : 
      69            3 :   @override
      70            6 :   bool get enabled => _meter.enabled;
      71              : 
      72            4 :   @override
      73            4 :   APIMeter get meter => _meter;
      74              : 
      75            0 :   @override
      76            0 :   List<double>? get boundaries => _apiHistogram.boundaries;
      77              : 
      78            1 :   @override
      79              :   bool get isCounter => false;
      80              : 
      81            1 :   @override
      82              :   bool get isUpDownCounter => false;
      83              : 
      84            1 :   @override
      85              :   bool get isGauge => false;
      86              : 
      87            1 :   @override
      88              :   bool get isHistogram => true;
      89              : 
      90            3 :   @override
      91              :   void record(T value, [Attributes? attributes]) {
      92              :     // First use the API implementation (no-op by default)
      93            6 :     _apiHistogram.record(value, attributes);
      94              : 
      95              :     // Only record if enabled
      96            3 :     if (!enabled) return;
      97              : 
      98              :     // Record the measurement in our storage
      99            6 :     _storage.record(value, attributes);
     100              :   }
     101              : 
     102            1 :   @override
     103              :   void recordWithMap(T value, Map<String, Object> attributeMap) {
     104              :     // Just convert to Attributes and call record
     105              :     final attributes =
     106            2 :         attributeMap.isEmpty ? null : attributeMap.toAttributes();
     107            1 :     record(value, attributes);
     108              :   }
     109              : 
     110              :   /// Gets the current histogram value for the given attributes.
     111              :   /// If no attributes are provided, returns the histogram value for the null/empty attribute set.
     112            1 :   HistogramValue getValue([Attributes? attributes]) {
     113            2 :     return _storage.getValue(attributes);
     114              :   }
     115              : 
     116              :   /// Gets the current points for this histogram.
     117              :   /// This is used by the SDK to collect metrics.
     118            3 :   List<MetricPoint<HistogramValue>> collectPoints() {
     119            6 :     return _storage.collectPoints();
     120              :   }
     121              : 
     122            3 :   @override
     123              :   List<Metric> collectMetrics() {
     124            4 :     if (!enabled) return [];
     125              : 
     126              :     // Get the points from storage
     127            3 :     final points = collectPoints();
     128              : 
     129            3 :     if (points.isEmpty) return [];
     130              : 
     131              :     // Create a metric with the collected points
     132            3 :     final metric = Metric(
     133            3 :       name: name,
     134            3 :       description: description,
     135            3 :       unit: unit,
     136              :       type: MetricType.histogram,
     137              :       points: points,
     138              :     );
     139              : 
     140            3 :     return [metric];
     141              :   }
     142              : 
     143              :   /// Resets the histogram. This is only used for Delta temporality.
     144            1 :   void reset() {
     145            2 :     _storage.reset();
     146              :   }
     147              : }
        

Generated by: LCOV version 2.0-1