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