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