opentelemetry-metrics-sdk 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -5
- data/lib/opentelemetry/sdk/metrics/aggregation/aggregation_temporality.rb +62 -0
- data/lib/opentelemetry/sdk/metrics/aggregation/drop.rb +6 -4
- data/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb +7 -5
- data/lib/opentelemetry/sdk/metrics/aggregation/exponential_bucket_histogram.rb +13 -9
- data/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb +6 -4
- data/lib/opentelemetry/sdk/metrics/aggregation/sum.rb +7 -6
- data/lib/opentelemetry/sdk/metrics/aggregation.rb +1 -0
- data/lib/opentelemetry/sdk/metrics/instrument/asynchronous_instrument.rb +93 -0
- data/lib/opentelemetry/sdk/metrics/instrument/observable_counter.rb +24 -9
- data/lib/opentelemetry/sdk/metrics/instrument/observable_gauge.rb +24 -9
- data/lib/opentelemetry/sdk/metrics/instrument/observable_up_down_counter.rb +24 -9
- data/lib/opentelemetry/sdk/metrics/instrument.rb +1 -0
- data/lib/opentelemetry/sdk/metrics/meter.rb +25 -1
- data/lib/opentelemetry/sdk/metrics/meter_provider.rb +1 -0
- data/lib/opentelemetry/sdk/metrics/state/asynchronous_metric_stream.rb +81 -0
- data/lib/opentelemetry/sdk/metrics/state.rb +1 -0
- data/lib/opentelemetry/sdk/metrics/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 85882c7aaf7937f0442c130f4d350cf4b94a47e69b90022010ad09a66d5b4e50
|
4
|
+
data.tar.gz: 04a4e258be416b2a66bbd27a1caa64bfce75cd411a1fad90ecbc757dc3a86c06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: acd461eca177defb59f52887c77a1e2e4f65b1318da5de8f30c64e2afd7e7358d1316df4c86232e1d8178dc7f88548648e7cc9f25c2d52adadc869edc8f9feb6
|
7
|
+
data.tar.gz: a31db4511b453827cc0059884a0fd59b5767ed78db562e3d3b5e048960c0283164658a5054a9f398ef48cac9e245dfd9697da55d1d9155b8de60847f5e798f20
|
data/CHANGELOG.md
CHANGED
@@ -1,24 +1,33 @@
|
|
1
1
|
# Release History: opentelemetry-metrics-sdk
|
2
2
|
|
3
|
+
### v0.8.0 / 2025-08-14
|
4
|
+
|
5
|
+
- BREAKING CHANGE: Update default aggregation temporality for counter, histogram, and up down counter to cumulative
|
6
|
+
|
7
|
+
- ADDED: Support asynchronous instruments: ObservableGauge, ObservableCounter and ObservableUpDownCounter
|
8
|
+
- FIXED: Validate scale range on exponential histograms and raise exception if out of bounds
|
9
|
+
- FIXED: Update max instrument name length from 63 to 255 characters and allow `/` in instrument names
|
10
|
+
- FIXED: Validate scale range and raise exception if out of bounds for exponential histograms
|
11
|
+
|
3
12
|
### v0.7.3 / 2025-07-09
|
4
13
|
|
5
|
-
|
14
|
+
- FIXED: Stop exporting metrics with empty data points
|
6
15
|
|
7
16
|
### v0.7.2 / 2025-07-03
|
8
17
|
|
9
|
-
|
18
|
+
- FIXED: Coerce aggregation temporality to be a symbol for exponential histograms
|
10
19
|
|
11
20
|
### v0.7.1 / 2025-05-28
|
12
21
|
|
13
|
-
|
22
|
+
- FIXED: Recover periodic metric readers after forking
|
14
23
|
|
15
24
|
### v0.7.0 / 2025-05-13
|
16
25
|
|
17
|
-
|
26
|
+
- ADDED: Add basic exponential histogram
|
18
27
|
|
19
28
|
### v0.6.1 / 2025-04-09
|
20
29
|
|
21
|
-
|
30
|
+
- FIXED: Use condition signal to replace sleep and remove timeout.timeout…
|
22
31
|
|
23
32
|
### v0.6.0 / 2025-02-25
|
24
33
|
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Metrics
|
10
|
+
module Aggregation
|
11
|
+
# AggregationTemporality represents the temporality of
|
12
|
+
# data point ({NumberDataPoint} and {HistogramDataPoint}) in {Metrics}.
|
13
|
+
# It determine whether the data point will be cleared for each metrics pull/export.
|
14
|
+
class AggregationTemporality
|
15
|
+
class << self
|
16
|
+
private :new
|
17
|
+
|
18
|
+
# Returns a newly created {AggregationTemporality} with temporality == DELTA
|
19
|
+
#
|
20
|
+
# @return [AggregationTemporality]
|
21
|
+
def delta
|
22
|
+
new(DELTA)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns a newly created {AggregationTemporality} with temporality == CUMULATIVE
|
26
|
+
#
|
27
|
+
# @return [AggregationTemporality]
|
28
|
+
def cumulative
|
29
|
+
new(CUMULATIVE)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :temporality
|
34
|
+
|
35
|
+
# @api private
|
36
|
+
# The constructor is private and only for use internally by the class.
|
37
|
+
# Users should use the {delta} and {cumulative} factory methods to obtain
|
38
|
+
# a {AggregationTemporality} instance.
|
39
|
+
#
|
40
|
+
# @param [Integer] temporality One of the status codes below
|
41
|
+
def initialize(temporality)
|
42
|
+
@temporality = temporality
|
43
|
+
end
|
44
|
+
|
45
|
+
def delta?
|
46
|
+
@temporality == :delta
|
47
|
+
end
|
48
|
+
|
49
|
+
def cumulative?
|
50
|
+
@temporality == :cumulative
|
51
|
+
end
|
52
|
+
|
53
|
+
# delta: data point will be cleared after each metrics pull/export.
|
54
|
+
DELTA = :delta
|
55
|
+
|
56
|
+
# cumulative: data point will NOT be cleared after metrics pull/export.
|
57
|
+
CUMULATIVE = :cumulative
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -10,10 +10,8 @@ module OpenTelemetry
|
|
10
10
|
module Aggregation
|
11
11
|
# Contains the implementation of the Drop aggregation
|
12
12
|
class Drop
|
13
|
-
|
14
|
-
|
15
|
-
def initialize(aggregation_temporality: :delta)
|
16
|
-
@aggregation_temporality = aggregation_temporality
|
13
|
+
def initialize
|
14
|
+
@aggregation_temporality = nil
|
17
15
|
end
|
18
16
|
|
19
17
|
def collect(start_time, end_time, data_points)
|
@@ -30,6 +28,10 @@ module OpenTelemetry
|
|
30
28
|
)
|
31
29
|
nil
|
32
30
|
end
|
31
|
+
|
32
|
+
def aggregation_temporality
|
33
|
+
nil
|
34
|
+
end
|
33
35
|
end
|
34
36
|
end
|
35
37
|
end
|
@@ -14,24 +14,22 @@ module OpenTelemetry
|
|
14
14
|
DEFAULT_BOUNDARIES = [0, 5, 10, 25, 50, 75, 100, 250, 500, 1000].freeze
|
15
15
|
private_constant :DEFAULT_BOUNDARIES
|
16
16
|
|
17
|
-
attr_reader :aggregation_temporality
|
18
|
-
|
19
17
|
# The default value for boundaries represents the following buckets:
|
20
18
|
# (-inf, 0], (0, 5.0], (5.0, 10.0], (10.0, 25.0], (25.0, 50.0],
|
21
19
|
# (50.0, 75.0], (75.0, 100.0], (100.0, 250.0], (250.0, 500.0],
|
22
20
|
# (500.0, 1000.0], (1000.0, +inf)
|
23
21
|
def initialize(
|
24
|
-
aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :
|
22
|
+
aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :cumulative),
|
25
23
|
boundaries: DEFAULT_BOUNDARIES,
|
26
24
|
record_min_max: true
|
27
25
|
)
|
28
|
-
@aggregation_temporality = aggregation_temporality.to_sym
|
26
|
+
@aggregation_temporality = aggregation_temporality.to_sym == :delta ? AggregationTemporality.delta : AggregationTemporality.cumulative
|
29
27
|
@boundaries = boundaries && !boundaries.empty? ? boundaries.sort : nil
|
30
28
|
@record_min_max = record_min_max
|
31
29
|
end
|
32
30
|
|
33
31
|
def collect(start_time, end_time, data_points)
|
34
|
-
if @aggregation_temporality
|
32
|
+
if @aggregation_temporality.delta?
|
35
33
|
# Set timestamps and 'move' data point values to result.
|
36
34
|
hdps = data_points.values.map! do |hdp|
|
37
35
|
hdp.start_time_unix_nano = start_time
|
@@ -87,6 +85,10 @@ module OpenTelemetry
|
|
87
85
|
nil
|
88
86
|
end
|
89
87
|
|
88
|
+
def aggregation_temporality
|
89
|
+
@aggregation_temporality.temporality
|
90
|
+
end
|
91
|
+
|
90
92
|
private
|
91
93
|
|
92
94
|
def empty_bucket_counts
|
@@ -19,15 +19,18 @@ module OpenTelemetry
|
|
19
19
|
attr_reader :aggregation_temporality
|
20
20
|
|
21
21
|
# relate to min max scale: https://opentelemetry.io/docs/specs/otel/metrics/sdk/#support-a-minimum-and-maximum-scale
|
22
|
+
DEFAULT_SIZE = 160
|
23
|
+
DEFAULT_SCALE = 20
|
22
24
|
MAX_SCALE = 20
|
23
25
|
MIN_SCALE = -10
|
24
|
-
|
26
|
+
MIN_MAX_SIZE = 2
|
27
|
+
MAX_MAX_SIZE = 16_384
|
25
28
|
|
26
29
|
# The default boundaries are calculated based on default max_size and max_scale values
|
27
30
|
def initialize(
|
28
31
|
aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta),
|
29
|
-
max_size:
|
30
|
-
max_scale:
|
32
|
+
max_size: DEFAULT_SIZE,
|
33
|
+
max_scale: DEFAULT_SCALE,
|
31
34
|
record_min_max: true,
|
32
35
|
zero_threshold: 0
|
33
36
|
)
|
@@ -175,6 +178,7 @@ module OpenTelemetry
|
|
175
178
|
end
|
176
179
|
|
177
180
|
def new_mapping(scale)
|
181
|
+
scale = validate_scale(scale)
|
178
182
|
scale <= 0 ? ExponentialHistogram::ExponentMapping.new(scale) : ExponentialHistogram::LogarithmMapping.new(scale)
|
179
183
|
end
|
180
184
|
|
@@ -203,17 +207,17 @@ module OpenTelemetry
|
|
203
207
|
end
|
204
208
|
|
205
209
|
def validate_scale(scale)
|
206
|
-
|
210
|
+
raise ArgumentError, "Scale #{scale} is larger than maximum scale #{MAX_SCALE}" if scale > MAX_SCALE
|
211
|
+
raise ArgumentError, "Scale #{scale} is smaller than minimum scale #{MIN_SCALE}" if scale < MIN_SCALE
|
207
212
|
|
208
|
-
|
209
|
-
MAX_SCALE
|
213
|
+
scale
|
210
214
|
end
|
211
215
|
|
212
216
|
def validate_size(size)
|
213
|
-
|
217
|
+
raise ArgumentError, "Max size #{size} is smaller than minimum size #{MIN_MAX_SIZE}" if size < MIN_MAX_SIZE
|
218
|
+
raise ArgumentError, "Max size #{size} is larger than maximum size #{MAX_MAX_SIZE}" if size > MAX_MAX_SIZE
|
214
219
|
|
215
|
-
|
216
|
-
MAX_SIZE
|
220
|
+
size
|
217
221
|
end
|
218
222
|
end
|
219
223
|
end
|
@@ -10,14 +10,12 @@ module OpenTelemetry
|
|
10
10
|
module Aggregation
|
11
11
|
# Contains the implementation of the LastValue aggregation
|
12
12
|
class LastValue
|
13
|
-
attr_reader :aggregation_temporality
|
14
|
-
|
15
13
|
def initialize(aggregation_temporality: :delta)
|
16
|
-
@aggregation_temporality = aggregation_temporality
|
14
|
+
@aggregation_temporality = aggregation_temporality == :cumulative ? AggregationTemporality.cumulative : AggregationTemporality.delta
|
17
15
|
end
|
18
16
|
|
19
17
|
def collect(start_time, end_time, data_points)
|
20
|
-
if @aggregation_temporality
|
18
|
+
if @aggregation_temporality.delta?
|
21
19
|
# Set timestamps and 'move' data point values to result.
|
22
20
|
ndps = data_points.values.map! do |ndp|
|
23
21
|
ndp.start_time_unix_nano = start_time
|
@@ -46,6 +44,10 @@ module OpenTelemetry
|
|
46
44
|
)
|
47
45
|
nil
|
48
46
|
end
|
47
|
+
|
48
|
+
def aggregation_temporality
|
49
|
+
@aggregation_temporality.temporality
|
50
|
+
end
|
49
51
|
end
|
50
52
|
end
|
51
53
|
end
|
@@ -11,16 +11,13 @@ module OpenTelemetry
|
|
11
11
|
# Contains the implementation of the Sum aggregation
|
12
12
|
# https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation
|
13
13
|
class Sum
|
14
|
-
|
15
|
-
|
16
|
-
def initialize(aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta), monotonic: false)
|
17
|
-
# TODO: the default should be :cumulative, see issue #1555
|
18
|
-
@aggregation_temporality = aggregation_temporality.to_sym
|
14
|
+
def initialize(aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :cumulative), monotonic: false)
|
15
|
+
@aggregation_temporality = aggregation_temporality.to_sym == :delta ? AggregationTemporality.delta : AggregationTemporality.cumulative
|
19
16
|
@monotonic = monotonic
|
20
17
|
end
|
21
18
|
|
22
19
|
def collect(start_time, end_time, data_points)
|
23
|
-
if @aggregation_temporality
|
20
|
+
if @aggregation_temporality.delta?
|
24
21
|
# Set timestamps and 'move' data point values to result.
|
25
22
|
ndps = data_points.values.map! do |ndp|
|
26
23
|
ndp.start_time_unix_nano = start_time
|
@@ -57,6 +54,10 @@ module OpenTelemetry
|
|
57
54
|
ndp.value += increment
|
58
55
|
nil
|
59
56
|
end
|
57
|
+
|
58
|
+
def aggregation_temporality
|
59
|
+
@aggregation_temporality.temporality
|
60
|
+
end
|
60
61
|
end
|
61
62
|
end
|
62
63
|
end
|
@@ -15,6 +15,7 @@ module OpenTelemetry
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
require 'opentelemetry/sdk/metrics/aggregation/aggregation_temporality'
|
18
19
|
require 'opentelemetry/sdk/metrics/aggregation/number_data_point'
|
19
20
|
require 'opentelemetry/sdk/metrics/aggregation/histogram_data_point'
|
20
21
|
require 'opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Metrics
|
10
|
+
module Instrument
|
11
|
+
# {AsynchronousInstrument} contains the common functionality shared across
|
12
|
+
# the asynchronous instruments SDK instruments.
|
13
|
+
class AsynchronousInstrument
|
14
|
+
def initialize(name, unit, description, callback, instrumentation_scope, meter_provider)
|
15
|
+
@name = name
|
16
|
+
@unit = unit
|
17
|
+
@description = description
|
18
|
+
@instrumentation_scope = instrumentation_scope
|
19
|
+
@meter_provider = meter_provider
|
20
|
+
@metric_streams = []
|
21
|
+
@callbacks = []
|
22
|
+
@timeout = nil
|
23
|
+
@attributes = {}
|
24
|
+
|
25
|
+
init_callback(callback)
|
26
|
+
meter_provider.register_asynchronous_instrument(self)
|
27
|
+
end
|
28
|
+
|
29
|
+
# @api private
|
30
|
+
def register_with_new_metric_store(metric_store, aggregation: default_aggregation)
|
31
|
+
ms = OpenTelemetry::SDK::Metrics::State::AsynchronousMetricStream.new(
|
32
|
+
@name,
|
33
|
+
@description,
|
34
|
+
@unit,
|
35
|
+
instrument_kind,
|
36
|
+
@meter_provider,
|
37
|
+
@instrumentation_scope,
|
38
|
+
aggregation,
|
39
|
+
@callbacks,
|
40
|
+
@timeout,
|
41
|
+
@attributes
|
42
|
+
)
|
43
|
+
@metric_streams << ms
|
44
|
+
metric_store.add_metric_stream(ms)
|
45
|
+
end
|
46
|
+
|
47
|
+
# The API MUST support creation of asynchronous instruments by passing zero or more callback functions
|
48
|
+
# to be permanently registered to the newly created instrument.
|
49
|
+
def init_callback(callback)
|
50
|
+
if callback.instance_of?(Proc)
|
51
|
+
@callbacks << callback
|
52
|
+
elsif callback.instance_of?(Array)
|
53
|
+
callback.each { |cb| @callbacks << cb if cb.instance_of?(Proc) }
|
54
|
+
else
|
55
|
+
OpenTelemetry.logger.warn "Only accept single Proc or Array of Proc for initialization with callback (given callback #{callback.class}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Where the API supports registration of callback functions after asynchronous instrumentation creation,
|
60
|
+
# the user MUST be able to undo registration of the specific callback after its registration by some means.
|
61
|
+
def register_callback(callback)
|
62
|
+
if callback.instance_of?(Proc)
|
63
|
+
@callbacks << callback
|
64
|
+
callback
|
65
|
+
else
|
66
|
+
OpenTelemetry.logger.warn "Only accept single Proc for registering callback (given callback #{callback.class}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def unregister(callback)
|
71
|
+
@callbacks.delete(callback)
|
72
|
+
end
|
73
|
+
|
74
|
+
def timeout(timeout)
|
75
|
+
@timeout = timeout
|
76
|
+
end
|
77
|
+
|
78
|
+
def add_attributes(attributes)
|
79
|
+
@attributes.merge!(attributes) if attributes.instance_of?(Hash)
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
# update the observed value (after calling observe)
|
85
|
+
# invoke callback will execute callback and export metric_data that is observed
|
86
|
+
def update(timeout, attributes)
|
87
|
+
@metric_streams.each { |ms| ms.invoke_callback(timeout, attributes) }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -8,16 +8,31 @@ module OpenTelemetry
|
|
8
8
|
module SDK
|
9
9
|
module Metrics
|
10
10
|
module Instrument
|
11
|
-
# {ObservableCounter} is the SDK implementation of {OpenTelemetry::Metrics::
|
12
|
-
|
13
|
-
|
11
|
+
# {ObservableCounter} is the SDK implementation of {OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument}.
|
12
|
+
# Asynchronous Counter is an asynchronous Instrument which reports monotonically increasing value(s) when the instrument is being observed.
|
13
|
+
class ObservableCounter < OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument
|
14
|
+
# Returns the instrument kind as a Symbol
|
15
|
+
#
|
16
|
+
# @return [Symbol]
|
17
|
+
def instrument_kind
|
18
|
+
:observable_counter
|
19
|
+
end
|
20
|
+
|
21
|
+
# Observe the ObservableCounter with fixed timeout duration.
|
22
|
+
#
|
23
|
+
# @param [int] timeout The timeout duration for callback to run, which MUST be a non-negative numeric value.
|
24
|
+
# @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
|
25
|
+
# Values must be non-nil and (array of) string, boolean or numeric type.
|
26
|
+
# Array values must not contain nil elements and all elements must be of
|
27
|
+
# the same basic type (string, numeric, boolean).
|
28
|
+
def observe(timeout: nil, attributes: {})
|
29
|
+
update(timeout, attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
14
33
|
|
15
|
-
def
|
16
|
-
|
17
|
-
@unit = unit
|
18
|
-
@description = description
|
19
|
-
@callback = callback
|
20
|
-
@meter = meter
|
34
|
+
def default_aggregation
|
35
|
+
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new(monotonic: true)
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -8,16 +8,31 @@ module OpenTelemetry
|
|
8
8
|
module SDK
|
9
9
|
module Metrics
|
10
10
|
module Instrument
|
11
|
-
# {ObservableGauge} is the SDK implementation of {OpenTelemetry::Metrics::
|
12
|
-
|
13
|
-
|
11
|
+
# {ObservableGauge} is the SDK implementation of {OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument}.
|
12
|
+
# Asynchronous Gauge is an asynchronous Instrument which reports non-additive value(s) (e.g. the room temperature)
|
13
|
+
class ObservableGauge < OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument
|
14
|
+
# Returns the instrument kind as a Symbol
|
15
|
+
#
|
16
|
+
# @return [Symbol]
|
17
|
+
def instrument_kind
|
18
|
+
:observable_gauge
|
19
|
+
end
|
20
|
+
|
21
|
+
# Observe the Gauge with fixed timeout duration.
|
22
|
+
#
|
23
|
+
# @param [int] timeout The timeout duration for callback to run, which MUST be a non-negative numeric value.
|
24
|
+
# @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
|
25
|
+
# Values must be non-nil and (array of) string, boolean or numeric type.
|
26
|
+
# Array values must not contain nil elements and all elements must be of
|
27
|
+
# the same basic type (string, numeric, boolean).
|
28
|
+
def observe(timeout: nil, attributes: {})
|
29
|
+
update(timeout, attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
14
33
|
|
15
|
-
def
|
16
|
-
|
17
|
-
@unit = unit
|
18
|
-
@description = description
|
19
|
-
@callback = callback
|
20
|
-
@meter = meter
|
34
|
+
def default_aggregation
|
35
|
+
OpenTelemetry::SDK::Metrics::Aggregation::LastValue.new
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -8,16 +8,31 @@ module OpenTelemetry
|
|
8
8
|
module SDK
|
9
9
|
module Metrics
|
10
10
|
module Instrument
|
11
|
-
# {ObservableUpDownCounter} is the SDK implementation of {OpenTelemetry::Metrics::
|
12
|
-
|
13
|
-
|
11
|
+
# {ObservableUpDownCounter} is the SDK implementation of {OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument}.
|
12
|
+
# Asynchronous UpDownCounter is an asynchronous Instrument which reports additive value(s) (e.g. the process heap size)
|
13
|
+
class ObservableUpDownCounter < OpenTelemetry::SDK::Metrics::Instrument::AsynchronousInstrument
|
14
|
+
# Returns the instrument kind as a Symbol
|
15
|
+
#
|
16
|
+
# @return [Symbol]
|
17
|
+
def instrument_kind
|
18
|
+
:observable_up_down_counter
|
19
|
+
end
|
20
|
+
|
21
|
+
# Observe the UpDownCounter with fixed timeout duration.
|
22
|
+
#
|
23
|
+
# @param [int] timeout The timeout duration for callback to run, which MUST be a non-negative numeric value.
|
24
|
+
# @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
|
25
|
+
# Values must be non-nil and (array of) string, boolean or numeric type.
|
26
|
+
# Array values must not contain nil elements and all elements must be of
|
27
|
+
# the same basic type (string, numeric, boolean).
|
28
|
+
def observe(timeout: nil, attributes: {})
|
29
|
+
update(timeout, attributes)
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
14
33
|
|
15
|
-
def
|
16
|
-
|
17
|
-
@unit = unit
|
18
|
-
@description = description
|
19
|
-
@callback = callback
|
20
|
-
@meter = meter
|
34
|
+
def default_aggregation
|
35
|
+
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new(aggregation_temporality: :delta, monotonic: false)
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -14,6 +14,7 @@ module OpenTelemetry
|
|
14
14
|
end
|
15
15
|
|
16
16
|
require 'opentelemetry/sdk/metrics/instrument/synchronous_instrument'
|
17
|
+
require 'opentelemetry/sdk/metrics/instrument/asynchronous_instrument'
|
17
18
|
require 'opentelemetry/sdk/metrics/instrument/counter'
|
18
19
|
require 'opentelemetry/sdk/metrics/instrument/histogram'
|
19
20
|
require 'opentelemetry/sdk/metrics/instrument/observable_counter'
|
@@ -11,7 +11,7 @@ module OpenTelemetry
|
|
11
11
|
module Metrics
|
12
12
|
# {Meter} is the SDK implementation of {OpenTelemetry::Metrics::Meter}.
|
13
13
|
class Meter < OpenTelemetry::Metrics::Meter
|
14
|
-
NAME_REGEX =
|
14
|
+
NAME_REGEX = %r{\A[a-zA-Z][-./\w]{0,254}\z}
|
15
15
|
|
16
16
|
# @api private
|
17
17
|
#
|
@@ -28,6 +28,30 @@ module OpenTelemetry
|
|
28
28
|
@meter_provider = meter_provider
|
29
29
|
end
|
30
30
|
|
31
|
+
# Multiple-instrument callbacks
|
32
|
+
# Callbacks registered after the time of instrument creation MAY be associated with multiple instruments.
|
33
|
+
# Related spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#multiple-instrument-callbacks
|
34
|
+
# Related spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/api.md#synchronous-instrument-api
|
35
|
+
#
|
36
|
+
# @param [Array] instruments A list (or tuple, etc.) of Instruments used in the callback function.
|
37
|
+
# @param [Proc] callback A callback function
|
38
|
+
#
|
39
|
+
# It is RECOMMENDED that the API authors use one of the following forms for the callback function:
|
40
|
+
# The list (or tuple, etc.) returned by the callback function contains (Instrument, Measurement) pairs.
|
41
|
+
# the Observable Result parameter receives an additional (Instrument, Measurement) pairs
|
42
|
+
# Here it chose the second form
|
43
|
+
def register_callback(instruments, callback)
|
44
|
+
instruments.each do |instrument|
|
45
|
+
instrument.register_callback(callback)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def unregister(instruments, callback)
|
50
|
+
instruments.each do |instrument|
|
51
|
+
instrument.unregister(callback)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
31
55
|
# @api private
|
32
56
|
def add_metric_reader(metric_reader)
|
33
57
|
@instrument_registry.each_value do |instrument|
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
module OpenTelemetry
|
8
|
+
module SDK
|
9
|
+
module Metrics
|
10
|
+
module State
|
11
|
+
# @api private
|
12
|
+
#
|
13
|
+
# The AsynchronousMetricStream class provides SDK internal functionality that is not a part of the
|
14
|
+
# public API. It extends MetricStream to support asynchronous instruments.
|
15
|
+
class AsynchronousMetricStream < MetricStream
|
16
|
+
def initialize(
|
17
|
+
name,
|
18
|
+
description,
|
19
|
+
unit,
|
20
|
+
instrument_kind,
|
21
|
+
meter_provider,
|
22
|
+
instrumentation_scope,
|
23
|
+
aggregation,
|
24
|
+
callback,
|
25
|
+
timeout,
|
26
|
+
attributes
|
27
|
+
)
|
28
|
+
# Call parent constructor with common parameters
|
29
|
+
super(name, description, unit, instrument_kind, meter_provider, instrumentation_scope, aggregation)
|
30
|
+
|
31
|
+
# Initialize asynchronous-specific attributes
|
32
|
+
@callback = callback
|
33
|
+
@start_time = now_in_nano
|
34
|
+
@timeout = timeout
|
35
|
+
@attributes = attributes
|
36
|
+
end
|
37
|
+
|
38
|
+
# When collect, if there are asynchronous SDK Instruments involved, their callback functions will be triggered.
|
39
|
+
# Related spec: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#collect
|
40
|
+
# invoke_callback will update the data_points in aggregation
|
41
|
+
def collect(start_time, end_time)
|
42
|
+
invoke_callback(@timeout, @attributes)
|
43
|
+
|
44
|
+
# Call parent collect method for the core collection logic
|
45
|
+
super(start_time, end_time)
|
46
|
+
end
|
47
|
+
|
48
|
+
def invoke_callback(timeout, attributes)
|
49
|
+
if @registered_views.empty?
|
50
|
+
@mutex.synchronize do
|
51
|
+
Timeout.timeout(timeout || 30) do
|
52
|
+
@callback.each do |cb|
|
53
|
+
value = cb.call
|
54
|
+
@default_aggregation.update(value, attributes, @data_points)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
else
|
59
|
+
@registered_views.each do |view|
|
60
|
+
@mutex.synchronize do
|
61
|
+
Timeout.timeout(timeout || 30) do
|
62
|
+
@callback.each do |cb|
|
63
|
+
value = cb.call
|
64
|
+
merged_attributes = attributes || {}
|
65
|
+
merged_attributes.merge!(view.attribute_keys)
|
66
|
+
view.aggregation.update(value, merged_attributes, @data_points) if view.valid_aggregation?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def now_in_nano
|
75
|
+
(Time.now.to_r * 1_000_000_000).to_i
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opentelemetry-metrics-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OpenTelemetry Authors
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-
|
11
|
+
date: 2025-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: opentelemetry-api
|
@@ -206,6 +206,7 @@ files:
|
|
206
206
|
- lib/opentelemetry-metrics-sdk.rb
|
207
207
|
- lib/opentelemetry/sdk/metrics.rb
|
208
208
|
- lib/opentelemetry/sdk/metrics/aggregation.rb
|
209
|
+
- lib/opentelemetry/sdk/metrics/aggregation/aggregation_temporality.rb
|
209
210
|
- lib/opentelemetry/sdk/metrics/aggregation/drop.rb
|
210
211
|
- lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb
|
211
212
|
- lib/opentelemetry/sdk/metrics/aggregation/exponential_bucket_histogram.rb
|
@@ -227,6 +228,7 @@ files:
|
|
227
228
|
- lib/opentelemetry/sdk/metrics/export/periodic_metric_reader.rb
|
228
229
|
- lib/opentelemetry/sdk/metrics/fork_hooks.rb
|
229
230
|
- lib/opentelemetry/sdk/metrics/instrument.rb
|
231
|
+
- lib/opentelemetry/sdk/metrics/instrument/asynchronous_instrument.rb
|
230
232
|
- lib/opentelemetry/sdk/metrics/instrument/counter.rb
|
231
233
|
- lib/opentelemetry/sdk/metrics/instrument/gauge.rb
|
232
234
|
- lib/opentelemetry/sdk/metrics/instrument/histogram.rb
|
@@ -238,6 +240,7 @@ files:
|
|
238
240
|
- lib/opentelemetry/sdk/metrics/meter.rb
|
239
241
|
- lib/opentelemetry/sdk/metrics/meter_provider.rb
|
240
242
|
- lib/opentelemetry/sdk/metrics/state.rb
|
243
|
+
- lib/opentelemetry/sdk/metrics/state/asynchronous_metric_stream.rb
|
241
244
|
- lib/opentelemetry/sdk/metrics/state/metric_data.rb
|
242
245
|
- lib/opentelemetry/sdk/metrics/state/metric_store.rb
|
243
246
|
- lib/opentelemetry/sdk/metrics/state/metric_stream.rb
|
@@ -248,10 +251,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby
|
|
248
251
|
licenses:
|
249
252
|
- Apache-2.0
|
250
253
|
metadata:
|
251
|
-
changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-metrics-sdk/v0.
|
254
|
+
changelog_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-metrics-sdk/v0.8.0/file.CHANGELOG.html
|
252
255
|
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby/tree/main/metrics_sdk
|
253
256
|
bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby/issues
|
254
|
-
documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-metrics-sdk/v0.
|
257
|
+
documentation_uri: https://open-telemetry.github.io/opentelemetry-ruby/opentelemetry-metrics-sdk/v0.8.0
|
255
258
|
post_install_message:
|
256
259
|
rdoc_options: []
|
257
260
|
require_paths:
|