Skip to content

Commit c2cb6cf

Browse files
committed
feat: advisory parameters for metrics instruments
1 parent baeda39 commit c2cb6cf

File tree

14 files changed

+153
-32
lines changed

14 files changed

+153
-32
lines changed

metrics_api/lib/opentelemetry/metrics/meter.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ def initialize
4343
# @param description [optional String] an optional free-form text provided by user.
4444
#
4545
# @return [nil] after creation of counter, it will be stored in instrument_registry
46-
def create_counter(name, unit: nil, description: nil)
47-
create_instrument(:counter, name, unit, description, nil) { COUNTER }
46+
def create_counter(name, unit: nil, description: nil, **advisory_parameters)
47+
create_instrument(:counter, name, unit, description, nil, **advisory_parameters) { COUNTER }
4848
end
4949

5050
# Histogram is a synchronous Instrument which can be used to report arbitrary values that are likely
@@ -62,8 +62,8 @@ def create_counter(name, unit: nil, description: nil)
6262
# @param description [optional String] an optional free-form text provided by user.
6363
#
6464
# @return [nil] after creation of histogram, it will be stored in instrument_registry
65-
def create_histogram(name, unit: nil, description: nil)
66-
create_instrument(:histogram, name, unit, description, nil) { HISTOGRAM }
65+
def create_histogram(name, unit: nil, description: nil, **advisory_parameters)
66+
create_instrument(:histogram, name, unit, description, nil, **advisory_parameters) { HISTOGRAM }
6767
end
6868

6969
# Gauge is an synchronous Instrument which reports non-additive value(s)
@@ -80,8 +80,8 @@ def create_histogram(name, unit: nil, description: nil)
8080
# @param description [optional String] an optional free-form text provided by user.
8181
#
8282
# @return [nil] after creation of gauge, it will be stored in instrument_registry
83-
def create_gauge(name, unit: nil, description: nil)
84-
create_instrument(:gauge, name, unit, description, nil) { GAUGE }
83+
def create_gauge(name, unit: nil, description: nil, **advisory_parameters)
84+
create_instrument(:gauge, name, unit, description, nil, **advisory_parameters) { GAUGE }
8585
end
8686

8787
# UpDownCounter is a synchronous Instrument which supports increments and decrements.
@@ -97,8 +97,8 @@ def create_gauge(name, unit: nil, description: nil)
9797
# @param description [optional String] an optional free-form text provided by user.
9898
#
9999
# @return [nil] after creation of up_down_counter, it will be stored in instrument_registry
100-
def create_up_down_counter(name, unit: nil, description: nil)
101-
create_instrument(:up_down_counter, name, unit, description, nil) { UP_DOWN_COUNTER }
100+
def create_up_down_counter(name, unit: nil, description: nil, **advisory_parameters)
101+
create_instrument(:up_down_counter, name, unit, description, nil, **advisory_parameters) { UP_DOWN_COUNTER }
102102
end
103103

104104
# ObservableCounter is an asynchronous Instrument which reports monotonically
@@ -119,8 +119,8 @@ def create_up_down_counter(name, unit: nil, description: nil)
119119
# @param description [optional String] an optional free-form text provided by user.
120120
#
121121
# @return [nil] after creation of observable_counter, it will be stored in instrument_registry
122-
def create_observable_counter(name, callback:, unit: nil, description: nil)
123-
create_instrument(:observable_counter, name, unit, description, callback) { OBSERVABLE_COUNTER }
122+
def create_observable_counter(name, callback:, unit: nil, description: nil, **advisory_parameters)
123+
create_instrument(:observable_counter, name, unit, description, callback, **advisory_parameters) { OBSERVABLE_COUNTER }
124124
end
125125

126126
# ObservableGauge is an asynchronous Instrument which reports non-additive value(s)
@@ -142,8 +142,8 @@ def create_observable_counter(name, callback:, unit: nil, description: nil)
142142
# @param description [optional String] an optional free-form text provided by user.
143143
#
144144
# @return [nil] after creation of observable_gauge, it will be stored in instrument_registry
145-
def create_observable_gauge(name, callback:, unit: nil, description: nil)
146-
create_instrument(:observable_gauge, name, unit, description, callback) { OBSERVABLE_GAUGE }
145+
def create_observable_gauge(name, callback:, unit: nil, description: nil, **advisory_parameters)
146+
create_instrument(:observable_gauge, name, unit, description, callback, **advisory_parameters) { OBSERVABLE_GAUGE }
147147
end
148148

149149
# ObservableUpDownCounter is an asynchronous Instrument which reports additive value(s)
@@ -165,13 +165,13 @@ def create_observable_gauge(name, callback:, unit: nil, description: nil)
165165
# @param description [optional String] an optional free-form text provided by user.
166166
#
167167
# @return [nil] after creation of observable_up_down_counter, it will be stored in instrument_registry
168-
def create_observable_up_down_counter(name, callback:, unit: nil, description: nil)
169-
create_instrument(:observable_up_down_counter, name, unit, description, callback) { OBSERVABLE_UP_DOWN_COUNTER }
168+
def create_observable_up_down_counter(name, callback:, unit: nil, description: nil, **advisory_parameters)
169+
create_instrument(:observable_up_down_counter, name, unit, description, callback, **advisory_parameters) { OBSERVABLE_UP_DOWN_COUNTER }
170170
end
171171

172172
private
173173

174-
def create_instrument(kind, name, unit, description, callback)
174+
def create_instrument(kind, name, unit, description, callback, **)
175175
@mutex.synchronize do
176176
OpenTelemetry.logger.warn("duplicate instrument registration occurred for instrument #{name}") if @instrument_registry.include? name
177177

metrics_api/test/opentelemetry/metrics/meter_test.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,21 @@
2424
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::Counter)
2525
end
2626

27+
it 'test create_counter with advisory parameters' do
28+
counter = meter.create_counter('test', attributes: { 'test' => true })
29+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::Counter)
30+
end
31+
2732
it 'test create_histogram' do
2833
counter = meter.create_histogram('test')
2934
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::Histogram)
3035
end
3136

37+
it 'test create_histogram with advisory parameters' do
38+
histogram = meter.create_histogram('test', explicit_bucket_boundaries: [1, 2, 3])
39+
_(histogram.class).must_equal(OpenTelemetry::Metrics::Instrument::Histogram)
40+
end
41+
3242
it 'test create_up_down_counter' do
3343
counter = meter.create_up_down_counter('test')
3444
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::UpDownCounter)

metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/drop.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,18 @@ module Aggregation
1212
class Drop
1313
attr_reader :aggregation_temporality
1414

15-
def initialize(aggregation_temporality: :delta)
15+
def initialize(aggregation_temporality: :delta, attributes: nil)
1616
@aggregation_temporality = aggregation_temporality
17+
@attributes = attributes if attributes
1718
end
1819

1920
def collect(start_time, end_time, data_points)
2021
data_points.values.map!(&:dup)
2122
end
2223

2324
def update(increment, attributes, data_points)
25+
attributes = @attributes.merge(attributes) if @attributes
26+
2427
data_points[attributes] = NumberDataPoint.new(
2528
{},
2629
0,

metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ class ExplicitBucketHistogram
2323
def initialize(
2424
aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta), # TODO: the default should be :cumulative, see issue #1555
2525
boundaries: DEFAULT_BOUNDARIES,
26+
attributes: nil,
2627
record_min_max: true
2728
)
2829
@aggregation_temporality = aggregation_temporality.to_sym
2930
@boundaries = boundaries && !boundaries.empty? ? boundaries.sort : nil
3031
@record_min_max = record_min_max
32+
@attributes = attributes if attributes
3133
end
3234

3335
def collect(start_time, end_time, data_points)
@@ -53,6 +55,8 @@ def collect(start_time, end_time, data_points)
5355
end
5456

5557
def update(amount, attributes, data_points)
58+
attributes = @attributes.merge(attributes) if @attributes
59+
5660
hdp = data_points.fetch(attributes) do
5761
if @record_min_max
5862
min = Float::INFINITY

metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ module Aggregation
1212
class LastValue
1313
attr_reader :aggregation_temporality
1414

15-
def initialize(aggregation_temporality: :delta)
15+
def initialize(aggregation_temporality: :delta, attributes: nil)
1616
@aggregation_temporality = aggregation_temporality
17+
@attributes = attributes if attributes
1718
end
1819

1920
def collect(start_time, end_time, data_points)
@@ -37,6 +38,8 @@ def collect(start_time, end_time, data_points)
3738
end
3839

3940
def update(increment, attributes, data_points)
41+
attributes = @attributes.merge(attributes) if @attributes
42+
4043
data_points[attributes] = NumberDataPoint.new(
4144
attributes,
4245
nil,

metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/sum.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,13 @@ module Aggregation
1313
class Sum
1414
attr_reader :aggregation_temporality
1515

16-
def initialize(aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta))
16+
def initialize(
17+
aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta),
18+
attributes: nil
19+
)
1720
# TODO: the default should be :cumulative, see issue #1555
1821
@aggregation_temporality = aggregation_temporality.to_sym
22+
@attributes = attributes if attributes
1923
end
2024

2125
def collect(start_time, end_time, data_points)
@@ -39,6 +43,8 @@ def collect(start_time, end_time, data_points)
3943
end
4044

4145
def update(increment, attributes, data_points)
46+
attributes = @attributes.merge(attributes) if @attributes
47+
4248
ndp = data_points[attributes] || data_points[attributes] = NumberDataPoint.new(
4349
attributes,
4450
nil,

metrics_sdk/lib/opentelemetry/sdk/metrics/instrument/counter.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def add(increment, attributes: {})
4242
private
4343

4444
def default_aggregation
45-
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new
45+
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new(attributes: @attributes)
4646
end
4747
end
4848
end

metrics_sdk/lib/opentelemetry/sdk/metrics/instrument/gauge.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def record(value, attributes: {})
3838
private
3939

4040
def default_aggregation
41-
OpenTelemetry::SDK::Metrics::Aggregation::LastValue.new
41+
OpenTelemetry::SDK::Metrics::Aggregation::LastValue.new(attributes: @attributes)
4242
end
4343
end
4444
end

metrics_sdk/lib/opentelemetry/sdk/metrics/instrument/histogram.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,21 @@ def record(amount, attributes: {})
3535
private
3636

3737
def default_aggregation
38-
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new
38+
# This hash is assembled to avoid implicitly passing `boundaries: nil`,
39+
# which should be valid explicit call according to ExplicitBucketHistogram#initialize
40+
kwargs = {}
41+
kwargs[:attributes] = @attributes if @attributes
42+
kwargs[:boundaries] = @boundaries if @boundaries
43+
44+
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new(**kwargs)
45+
end
46+
47+
def validate_advisory_parameters(parameters)
48+
if (boundaries = parameters.delete(:explicit_bucket_boundaries))
49+
@boundaries = boundaries
50+
end
51+
52+
super
3953
end
4054
end
4155
end

metrics_sdk/lib/opentelemetry/sdk/metrics/instrument/synchronous_instrument.rb

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,21 @@ module Instrument
1111
# {SynchronousInstrument} contains the common functionality shared across
1212
# the synchronous instruments SDK instruments.
1313
class SynchronousInstrument
14-
def initialize(name, unit, description, instrumentation_scope, meter_provider)
14+
def initialize(name, unit, description, instrumentation_scope, meter_provider, **advisory_parameters)
1515
@name = name
1616
@unit = unit
1717
@description = description
1818
@instrumentation_scope = instrumentation_scope
1919
@meter_provider = meter_provider
2020
@metric_streams = []
2121

22+
validate_advisory_parameters(advisory_parameters)
23+
2224
meter_provider.register_synchronous_instrument(self)
2325
end
2426

2527
# @api private
26-
def register_with_new_metric_store(metric_store, aggregation: default_aggregation)
28+
def register_with_new_metric_store(metric_store)
2729
ms = OpenTelemetry::SDK::Metrics::State::MetricStream.new(
2830
@name,
2931
@description,
@@ -37,11 +39,25 @@ def register_with_new_metric_store(metric_store, aggregation: default_aggregatio
3739
metric_store.add_metric_stream(ms)
3840
end
3941

42+
def aggregation
43+
@aggregation || default_aggregation
44+
end
45+
4046
private
4147

4248
def update(value, attributes)
4349
@metric_streams.each { |ms| ms.update(value, attributes) }
4450
end
51+
52+
def validate_advisory_parameters(advisory_parameters)
53+
if (attributes = advisory_parameters.delete(:attributes))
54+
@attributes = attributes
55+
end
56+
57+
advisory_parameters.each_key do |parameter_name|
58+
OpenTelemetry.logger.warn "Advisory parameter `#{parameter_name}` is not valid for instrument kind `#{instrument_kind}`; ignoring"
59+
end
60+
end
4561
end
4662
end
4763
end

0 commit comments

Comments
 (0)