Skip to content

Commit 4b14d61

Browse files
Merge branch 'main' into update-exporter-appraisals
2 parents c9610ad + 4c9f7e1 commit 4b14d61

File tree

9 files changed

+138
-54
lines changed

9 files changed

+138
-54
lines changed

metrics_api/lib/opentelemetry/metrics/meter.rb

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ class Meter
1515
UP_DOWN_COUNTER = Instrument::UpDownCounter.new
1616
OBSERVABLE_UP_DOWN_COUNTER = Instrument::ObservableUpDownCounter.new
1717

18-
NAME_REGEX = /\A[a-zA-Z][-.\w]{0,62}\z/
19-
2018
private_constant(:COUNTER, :OBSERVABLE_COUNTER, :HISTOGRAM, :OBSERVABLE_GAUGE, :UP_DOWN_COUNTER, :OBSERVABLE_UP_DOWN_COUNTER)
2119

2220
DuplicateInstrumentError = Class.new(OpenTelemetry::Error)
@@ -56,23 +54,12 @@ def create_observable_up_down_counter(name, callback:, unit: nil, description: n
5654
private
5755

5856
def create_instrument(kind, name, unit, description, callback)
59-
raise InstrumentNameError if name.nil?
60-
raise InstrumentNameError if name.empty?
61-
raise InstrumentNameError unless NAME_REGEX.match?(name)
62-
raise InstrumentUnitError if unit && (!unit.ascii_only? || unit.size > 63)
63-
raise InstrumentDescriptionError if description && (description.size > 1023 || !utf8mb3_encoding?(description.dup))
64-
6557
@mutex.synchronize do
6658
OpenTelemetry.logger.warn("duplicate instrument registration occurred for instrument #{name}") if @instrument_registry.include? name
6759

6860
@instrument_registry[name] = yield
6961
end
7062
end
71-
72-
def utf8mb3_encoding?(string)
73-
string.force_encoding('UTF-8').valid_encoding? &&
74-
string.each_char { |c| return false if c.bytesize >= 4 }
75-
end
7663
end
7764
end
7865
end

metrics_api/test/opentelemetry/metrics/meter_test.rb

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
require 'test_helper'
88

99
describe OpenTelemetry::Metrics::Meter do
10-
INSTRUMENT_NAME_ERROR = OpenTelemetry::Metrics::Meter::InstrumentNameError
11-
INSTRUMENT_UNIT_ERROR = OpenTelemetry::Metrics::Meter::InstrumentUnitError
12-
INSTRUMENT_DESCRIPTION_ERROR = OpenTelemetry::Metrics::Meter::InstrumentDescriptionError
13-
DUPLICATE_INSTRUMENT_ERROR = OpenTelemetry::Metrics::Meter::DuplicateInstrumentError
14-
1510
let(:meter_provider) { OpenTelemetry::Metrics::MeterProvider.new }
1611
let(:meter) { meter_provider.meter('test-meter') }
1712

@@ -24,50 +19,34 @@
2419
end
2520
end
2621

27-
it 'instrument name must not be nil' do
28-
_(-> { meter.create_counter(nil) }).must_raise(INSTRUMENT_NAME_ERROR)
29-
end
30-
31-
it 'instument name must not be an empty string' do
32-
_(-> { meter.create_counter('') }).must_raise(INSTRUMENT_NAME_ERROR)
33-
end
34-
35-
it 'instrument name must have an alphabetic first character' do
36-
_(meter.create_counter('one_counter'))
37-
_(-> { meter.create_counter('1_counter') }).must_raise(INSTRUMENT_NAME_ERROR)
38-
end
39-
40-
it 'instrument name must not exceed 63 character limit' do
41-
long_name = 'a' * 63
42-
meter.create_counter(long_name)
43-
_(-> { meter.create_counter(long_name + 'a') }).must_raise(INSTRUMENT_NAME_ERROR)
22+
it 'test create_counter' do
23+
counter = meter.create_counter('test')
24+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::Counter)
4425
end
4526

46-
it 'instrument name must belong to alphanumeric characters, _, ., and -' do
47-
meter.create_counter('a_-..-_a')
48-
_(-> { meter.create_counter('a@') }).must_raise(INSTRUMENT_NAME_ERROR)
49-
_(-> { meter.create_counter('a!') }).must_raise(INSTRUMENT_NAME_ERROR)
27+
it 'test create_histogram' do
28+
counter = meter.create_histogram('test')
29+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::Histogram)
5030
end
5131

52-
it 'instrument unit must be ASCII' do
53-
_(-> { meter.create_counter('a_counter', unit: 'á') }).must_raise(INSTRUMENT_UNIT_ERROR)
32+
it 'test create_up_down_counter' do
33+
counter = meter.create_up_down_counter('test')
34+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::UpDownCounter)
5435
end
5536

56-
it 'instrument unit must not exceed 63 characters' do
57-
long_unit = 'a' * 63
58-
meter.create_counter('a_counter', unit: long_unit)
59-
_(-> { meter.create_counter('b_counter', unit: long_unit + 'a') }).must_raise(INSTRUMENT_UNIT_ERROR)
37+
it 'test create_observable_counter' do
38+
counter = meter.create_observable_counter('test', callback: -> {})
39+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::ObservableCounter)
6040
end
6141

62-
it 'instrument description must be utf8mb3' do
63-
_(-> { meter.create_counter('a_counter', description: '💩'.dup) }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
64-
_(-> { meter.create_counter('b_counter', description: "\xc2".dup) }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
42+
it 'test create_observable_gauge' do
43+
counter = meter.create_observable_gauge('test', callback: -> {})
44+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::ObservableGauge)
6545
end
6646

67-
it 'instrument description must not exceed 1023 characters' do
68-
long_description = 'a' * 1023
69-
meter.create_counter('a_counter', description: long_description)
70-
_(-> { meter.create_counter('b_counter', description: long_description + 'a') }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
47+
it 'test create_observable_up_down_counter' do
48+
counter = meter.create_observable_up_down_counter('test', callback: -> {})
49+
_(counter.class).must_equal(OpenTelemetry::Metrics::Instrument::ObservableUpDownCounter)
7150
end
7251
end
7352
end

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ def initialize(
2525
boundaries: DEFAULT_BOUNDARIES,
2626
record_min_max: true
2727
)
28-
@aggregation_temporality = aggregation_temporality
28+
29+
@aggregation_temporality = aggregation_temporality.to_sym
2930
@boundaries = boundaries && !boundaries.empty? ? boundaries.sort : nil
3031
@record_min_max = record_min_max
3132
end

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class Sum
1515

1616
def initialize(aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta))
1717
# TODO: the default should be :cumulative, see issue #1555
18-
@aggregation_temporality = aggregation_temporality
18+
@aggregation_temporality = aggregation_temporality.to_sym
1919
end
2020

2121
def collect(start_time, end_time, data_points)

metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ module SDK
1111
module Metrics
1212
# {Meter} is the SDK implementation of {OpenTelemetry::Metrics::Meter}.
1313
class Meter < OpenTelemetry::Metrics::Meter
14+
NAME_REGEX = /\A[a-zA-Z][-.\w]{0,62}\z/
15+
1416
# @api private
1517
#
1618
# Returns a new {Meter} instance.
@@ -34,6 +36,12 @@ def add_metric_reader(metric_reader)
3436
end
3537

3638
def create_instrument(kind, name, unit, description, callback)
39+
raise InstrumentNameError if name.nil?
40+
raise InstrumentNameError if name.empty?
41+
raise InstrumentNameError unless NAME_REGEX.match?(name)
42+
raise InstrumentUnitError if unit && (!unit.ascii_only? || unit.size > 63)
43+
raise InstrumentDescriptionError if description && (description.size > 1023 || !utf8mb3_encoding?(description.dup))
44+
3745
super do
3846
case kind
3947
when :counter then OpenTelemetry::SDK::Metrics::Instrument::Counter.new(name, unit, description, @instrumentation_scope, @meter_provider)
@@ -45,6 +53,11 @@ def create_instrument(kind, name, unit, description, callback)
4553
end
4654
end
4755
end
56+
57+
def utf8mb3_encoding?(string)
58+
string.force_encoding('UTF-8').valid_encoding? &&
59+
string.each_char { |c| return false if c.bytesize >= 4 }
60+
end
4861
end
4962
end
5063
end

metrics_sdk/lib/opentelemetry/sdk/metrics/meter_provider.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ def meter(name, version: nil)
3737
OpenTelemetry.logger.warn 'calling MeterProvider#meter after shutdown, a noop meter will be returned.'
3838
OpenTelemetry::Metrics::Meter.new
3939
else
40+
OpenTelemetry.logger.warn "Invalid meter name provided: #{name.nil? ? 'nil' : 'empty'} value" if name.to_s.empty?
4041
@mutex.synchronize { @meter_registry[Key.new(name, version)] ||= Meter.new(name, version, self) }
4142
end
4243
end

metrics_sdk/test/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,27 @@
2222
let(:start_time) { (Time.now.to_r * 1_000_000_000).to_i }
2323
let(:end_time) { ((Time.now + 60).to_r * 1_000_000_000).to_i }
2424

25+
describe '#initialize' do
26+
it 'defaults to the delta aggregation temporality' do
27+
exp = OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new
28+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :delta
29+
end
30+
31+
it 'sets parameters from the environment and converts them to symbols' do
32+
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' => 'potato') do
33+
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new
34+
end
35+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :potato
36+
end
37+
38+
it 'prefers explicit parameters rather than the environment and converts them to symbols' do
39+
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' => 'potato') do
40+
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new(aggregation_temporality: 'pickles')
41+
end
42+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :pickles
43+
end
44+
end
45+
2546
describe '#collect' do
2647
it 'returns all the data points' do
2748
ebh.update(0, {}, data_points)

metrics_sdk/test/opentelemetry/sdk/metrics/aggregation/sum_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,27 @@
1515
let(:start_time) { (Time.now.to_r * 1_000_000_000).to_i }
1616
let(:end_time) { ((Time.now + 60).to_r * 1_000_000_000).to_i }
1717

18+
describe '#initialize' do
19+
it 'defaults to the delta aggregation temporality' do
20+
exp = OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new
21+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :delta
22+
end
23+
24+
it 'sets parameters from the environment and converts them to symbols' do
25+
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' => 'potato') do
26+
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new
27+
end
28+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :potato
29+
end
30+
31+
it 'prefers explicit parameters rather than the environment and converts them to symbols' do
32+
exp = OpenTelemetry::TestHelpers.with_env('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE' => 'potato') do
33+
OpenTelemetry::SDK::Metrics::Aggregation::ExplicitBucketHistogram.new(aggregation_temporality: 'pickles')
34+
end
35+
_(exp.instance_variable_get(:@aggregation_temporality)).must_equal :pickles
36+
end
37+
end
38+
1839
it 'sets the timestamps' do
1940
sum_aggregation.update(0, {}, data_points)
2041
ndp = sum_aggregation.collect(start_time, end_time, data_points)[0]

metrics_sdk/test/opentelemetry/sdk/metrics/meter_test.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,65 @@
5858
_(instrument).must_be_instance_of OpenTelemetry::SDK::Metrics::Instrument::ObservableUpDownCounter
5959
end
6060
end
61+
62+
describe 'creating an instrument' do
63+
INSTRUMENT_NAME_ERROR = OpenTelemetry::Metrics::Meter::InstrumentNameError
64+
INSTRUMENT_UNIT_ERROR = OpenTelemetry::Metrics::Meter::InstrumentUnitError
65+
INSTRUMENT_DESCRIPTION_ERROR = OpenTelemetry::Metrics::Meter::InstrumentDescriptionError
66+
DUPLICATE_INSTRUMENT_ERROR = OpenTelemetry::Metrics::Meter::DuplicateInstrumentError
67+
68+
it 'duplicate instrument registration logs a warning' do
69+
OpenTelemetry::TestHelpers.with_test_logger do |log_stream|
70+
meter.create_counter('a_counter')
71+
meter.create_counter('a_counter')
72+
_(log_stream.string).must_match(/duplicate instrument registration occurred for instrument a_counter/)
73+
end
74+
end
75+
76+
it 'instrument name must not be nil' do
77+
_(-> { meter.create_counter(nil) }).must_raise(INSTRUMENT_NAME_ERROR)
78+
end
79+
80+
it 'instument name must not be an empty string' do
81+
_(-> { meter.create_counter('') }).must_raise(INSTRUMENT_NAME_ERROR)
82+
end
83+
84+
it 'instrument name must have an alphabetic first character' do
85+
_(meter.create_counter('one_counter'))
86+
_(-> { meter.create_counter('1_counter') }).must_raise(INSTRUMENT_NAME_ERROR)
87+
end
88+
89+
it 'instrument name must not exceed 63 character limit' do
90+
long_name = 'a' * 63
91+
meter.create_counter(long_name)
92+
_(-> { meter.create_counter(long_name + 'a') }).must_raise(INSTRUMENT_NAME_ERROR)
93+
end
94+
95+
it 'instrument name must belong to alphanumeric characters, _, ., and -' do
96+
meter.create_counter('a_-..-_a')
97+
_(-> { meter.create_counter('a@') }).must_raise(INSTRUMENT_NAME_ERROR)
98+
_(-> { meter.create_counter('a!') }).must_raise(INSTRUMENT_NAME_ERROR)
99+
end
100+
101+
it 'instrument unit must be ASCII' do
102+
_(-> { meter.create_counter('a_counter', unit: 'á') }).must_raise(INSTRUMENT_UNIT_ERROR)
103+
end
104+
105+
it 'instrument unit must not exceed 63 characters' do
106+
long_unit = 'a' * 63
107+
meter.create_counter('a_counter', unit: long_unit)
108+
_(-> { meter.create_counter('b_counter', unit: long_unit + 'a') }).must_raise(INSTRUMENT_UNIT_ERROR)
109+
end
110+
111+
it 'instrument description must be utf8mb3' do
112+
_(-> { meter.create_counter('a_counter', description: '💩'.dup) }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
113+
_(-> { meter.create_counter('b_counter', description: "\xc2".dup) }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
114+
end
115+
116+
it 'instrument description must not exceed 1023 characters' do
117+
long_description = 'a' * 1023
118+
meter.create_counter('a_counter', description: long_description)
119+
_(-> { meter.create_counter('b_counter', description: long_description + 'a') }).must_raise(INSTRUMENT_DESCRIPTION_ERROR)
120+
end
121+
end
61122
end

0 commit comments

Comments
 (0)