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/gauge_storage.dart';
10 : import 'base_instrument.dart';
11 :
12 : /// Gauge is a synchronous instrument that records non-additive values.
13 : ///
14 : /// A Gauge is used to measure a non-additive value that represents the current
15 : /// state, such as temperature, memory usage, or CPU utilization.
16 : class Gauge<T extends num> implements APIGauge<T>, SDKInstrument {
17 : /// The underlying API Gauge.
18 : final APIGauge<T> _apiGauge;
19 :
20 : /// The Meter that created this Gauge.
21 : final Meter _meter;
22 :
23 : /// Storage for gauge measurements.
24 : final GaugeStorage<T> _storage = GaugeStorage<T>();
25 :
26 : /// Creates a new Gauge instance.
27 4 : Gauge({
28 : required APIGauge<T> apiGauge,
29 : required Meter meter,
30 : }) : _apiGauge = apiGauge,
31 : _meter = meter {
32 : // Register this instrument with the meter provider
33 20 : _meter.provider.registerInstrument(_meter.name, this);
34 : }
35 :
36 4 : @override
37 8 : String get name => _apiGauge.name;
38 :
39 3 : @override
40 6 : String? get unit => _apiGauge.unit;
41 :
42 3 : @override
43 6 : String? get description => _apiGauge.description;
44 :
45 3 : @override
46 6 : bool get enabled => _meter.enabled;
47 :
48 4 : @override
49 4 : APIMeter get meter => _meter;
50 :
51 1 : @override
52 : bool get isCounter => false;
53 :
54 1 : @override
55 : bool get isUpDownCounter => false;
56 :
57 1 : @override
58 : bool get isGauge => true;
59 :
60 1 : @override
61 : bool get isHistogram => false;
62 :
63 3 : @override
64 : void record(T value, [Attributes? attributes]) {
65 : // First use the API implementation (no-op by default)
66 6 : _apiGauge.record(value, attributes);
67 :
68 : // Only record if enabled
69 3 : if (!enabled) return;
70 :
71 : // Record the measurement in our storage
72 6 : _storage.record(value, attributes);
73 : }
74 :
75 1 : @override
76 : void recordWithMap(T value, Map<String, Object> attributeMap) {
77 : // Just convert to Attributes and call record
78 : final attributes =
79 2 : attributeMap.isEmpty ? null : attributeMap.toAttributes();
80 1 : record(value, attributes);
81 : }
82 :
83 : /// Gets the current value of the gauge for a specific set of attributes.
84 1 : T getValue(Attributes attributes) {
85 2 : final value = _storage.getValue(attributes);
86 : // Handle the cast to the generic type
87 2 : if (T == int) return value.toInt() as T;
88 0 : if (T == double) return value.toDouble() as T;
89 : return value;
90 : }
91 :
92 : /// Gets the current points for this gauge.
93 : /// This is used by the SDK to collect metrics.
94 3 : List<MetricPoint<T>> collectPoints() {
95 6 : return _storage.collectPoints();
96 : }
97 :
98 3 : @override
99 : List<Metric> collectMetrics() {
100 4 : if (!enabled) return [];
101 :
102 : // Get the points from storage
103 3 : final points = collectPoints();
104 :
105 3 : if (points.isEmpty) return [];
106 :
107 : // Create a metric with the collected points
108 3 : final metric = Metric(
109 3 : name: name,
110 3 : description: description,
111 3 : unit: unit,
112 : type: MetricType.gauge,
113 : points: points,
114 : );
115 :
116 3 : return [metric];
117 : }
118 : }
|