diff --git a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb index d2beac6d53..d6d87921f6 100644 --- a/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb +++ b/exporter/otlp-metrics/lib/opentelemetry/exporter/otlp/metrics/metrics_exporter.rb @@ -26,7 +26,7 @@ module Exporter module OTLP module Metrics # An OpenTelemetry metrics exporter that sends metrics over HTTP as Protobuf encoded OTLP ExportMetricsServiceRequest. - class MetricsExporter < ::OpenTelemetry::SDK::Metrics::Export::MetricReader + class MetricsExporter < ::OpenTelemetry::SDK::Metrics::Export::MetricExporter include Util attr_reader :metric_snapshots @@ -78,8 +78,8 @@ def initialize(endpoint: OpenTelemetry::Common::Utilities.config_opt('OTEL_EXPOR # consolidate the metrics data into the form of MetricData # # return MetricData - def pull - export(collect) + def pull(timeout: nil) + export(collect, timeout: timeout) end # metrics Array[MetricData] diff --git a/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb b/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb index 020d0e9a8d..ff192ac4be 100644 --- a/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb +++ b/exporter/otlp-metrics/test/opentelemetry/exporter/otlp/metrics/metrics_exporter_test.rb @@ -336,6 +336,7 @@ describe '#export' do let(:exporter) { OpenTelemetry::Exporter::OTLP::Metrics::MetricsExporter.new } + let(:metric_reader) { OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: exporter) } let(:meter_provider) { OpenTelemetry::SDK::Metrics::MeterProvider.new(resource: OpenTelemetry::SDK::Resources::Resource.telemetry_sdk) } it 'integrates with collector' do @@ -530,11 +531,11 @@ it 'exports a metric' do stub_post = stub_request(:post, 'http://localhost:4318/v1/metrics').to_return(status: 200) - meter_provider.add_metric_reader(exporter) + meter_provider.add_metric_reader(metric_reader) meter = meter_provider.meter('test') counter = meter.create_counter('test_counter', unit: 'smidgen', description: 'a small amount of something') counter.add(5, attributes: { 'foo' => 'bar' }) - exporter.pull + metric_reader.pull meter_provider.shutdown assert_requested(stub_post) @@ -574,7 +575,7 @@ it 'translates all the things' do stub_request(:post, 'http://localhost:4318/v1/metrics').to_return(status: 200) - meter_provider.add_metric_reader(exporter) + meter_provider.add_metric_reader(metric_reader) meter = meter_provider.meter('test') counter = meter.create_counter('test_counter', unit: 'smidgen', description: 'a small amount of something') @@ -586,7 +587,7 @@ gauge = meter.create_gauge('test_gauge', unit: 'smidgen', description: 'a small amount of something') gauge.record(15, attributes: { 'baz' => 'qux' }) - exporter.pull + metric_reader.pull meter_provider.shutdown encoded_etsr = Opentelemetry::Proto::Collector::Metrics::V1::ExportMetricsServiceRequest.encode( diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/drop.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/drop.rb index f638c649a5..a3290b6cce 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/drop.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/drop.rb @@ -10,7 +10,7 @@ module Metrics module Aggregation # Contains the implementation of the Drop aggregation class Drop - attr_reader :aggregation_temporality + attr_accessor :aggregation_temporality def initialize(aggregation_temporality: :delta) @aggregation_temporality = aggregation_temporality diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb index d379e0a9a4..2436c077ae 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/explicit_bucket_histogram.rb @@ -14,7 +14,9 @@ class ExplicitBucketHistogram DEFAULT_BOUNDARIES = [0, 5, 10, 25, 50, 75, 100, 250, 500, 1000].freeze private_constant :DEFAULT_BOUNDARIES - attr_reader :aggregation_temporality + attr_accessor :aggregation_temporality + + # attr_accessor :aggregation_temporality # approach 2 # The default value for boundaries represents the following buckets: # (-inf, 0], (0, 5.0], (5.0, 10.0], (10.0, 25.0], (25.0, 50.0], diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb index b2cffb74e2..dc48124f38 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/last_value.rb @@ -10,7 +10,7 @@ module Metrics module Aggregation # Contains the implementation of the LastValue aggregation class LastValue - attr_reader :aggregation_temporality + attr_accessor :aggregation_temporality def initialize(aggregation_temporality: :delta) @aggregation_temporality = aggregation_temporality diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/sum.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/sum.rb index c2771b38e3..fd41e044dd 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/sum.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/aggregation/sum.rb @@ -11,7 +11,7 @@ module Aggregation # Contains the implementation of the Sum aggregation # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md#sum-aggregation class Sum - attr_reader :aggregation_temporality + attr_accessor :aggregation_temporality def initialize(aggregation_temporality: ENV.fetch('OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE', :delta)) # TODO: the default should be :cumulative, see issue #1555 diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/configuration_patch.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/configuration_patch.rb index f9ee2c07fa..cd1d74e670 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/configuration_patch.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/configuration_patch.rb @@ -38,7 +38,7 @@ def wrapped_metric_exporters_from_env case exporter.strip when 'none' then nil when 'console' then OpenTelemetry.meter_provider.add_metric_reader(Metrics::Export::PeriodicMetricReader.new(exporter: Metrics::Export::ConsoleMetricPullExporter.new)) - when 'in-memory' then OpenTelemetry.meter_provider.add_metric_reader(Metrics::Export::InMemoryMetricPullExporter.new) + when 'in-memory' then OpenTelemetry.meter_provider.add_metric_reader(Metrics::Export::MetricReader.new(exporter: Metrics::Export::InMemoryMetricPullExporter.new)) when 'otlp' begin OpenTelemetry.meter_provider.add_metric_reader(Metrics::Export::PeriodicMetricReader.new(exporter: OpenTelemetry::Exporter::OTLP::Metrics::MetricsExporter.new)) diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export.rb index 782a75aae4..cd5ee075bf 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/export.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export.rb @@ -23,6 +23,7 @@ module Export end end +require 'opentelemetry/sdk/metrics/export/metric_exporter' require 'opentelemetry/sdk/metrics/export/metric_reader' require 'opentelemetry/sdk/metrics/export/in_memory_metric_pull_exporter' require 'opentelemetry/sdk/metrics/export/console_metric_pull_exporter' diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/console_metric_pull_exporter.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/console_metric_pull_exporter.rb index 8264c8e2e0..b23471a949 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/console_metric_pull_exporter.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/console_metric_pull_exporter.rb @@ -11,16 +11,12 @@ module Export # Outputs {MetricData} to the console # # Potentially useful for exploratory purposes. - class ConsoleMetricPullExporter < MetricReader + class ConsoleMetricPullExporter < MetricExporter def initialize super @stopped = false end - def pull - export(collect) - end - def export(metrics, timeout: nil) return FAILURE if @stopped diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/in_memory_metric_pull_exporter.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/in_memory_metric_pull_exporter.rb index d0d8ccb902..6b6d529598 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/in_memory_metric_pull_exporter.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/in_memory_metric_pull_exporter.rb @@ -10,7 +10,7 @@ module Metrics module Export # The InMemoryMetricPullExporter behaves as a Metric Reader and Exporter. # To be used for testing purposes, not production. - class InMemoryMetricPullExporter < MetricReader + class InMemoryMetricPullExporter < MetricExporter attr_reader :metric_snapshots def initialize @@ -19,10 +19,6 @@ def initialize @mutex = Mutex.new end - def pull - export(collect) - end - def export(metrics, timeout: nil) @mutex.synchronize do @metric_snapshots.concat(Array(metrics)) @@ -35,10 +31,6 @@ def reset @metric_snapshots.clear end end - - def shutdown - SUCCESS - end end end end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_exporter.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_exporter.rb new file mode 100644 index 0000000000..e384ee49b6 --- /dev/null +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_exporter.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +module OpenTelemetry + module SDK + module Metrics + module Export + # Exporter provides a minimal example implementation. + # It is not required to subclass this class to provide an implementation + # of MetricReader, provided the interface is satisfied. + class MetricExporter + attr_reader :metric_store + + def initialize + @metric_store = OpenTelemetry::SDK::Metrics::State::MetricStore.new + end + + def collect + @metric_store.collect + end + + def pull(timeout: nil) + export(collect, timeout: timeout) + end + + def export(metrics, timeout: nil) + Export::SUCCESS + end + + def shutdown(timeout: nil) + Export::SUCCESS + end + + def force_flush(timeout: nil) + Export::SUCCESS + end + end + end + end + end +end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_reader.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_reader.rb index c261f4f10a..4f85fa250b 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_reader.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/metric_reader.rb @@ -8,26 +8,69 @@ module OpenTelemetry module SDK module Metrics module Export - # MetricReader provides a minimal example implementation. - # It is not required to subclass this class to provide an implementation - # of MetricReader, provided the interface is satisfied. + # MetricReader class MetricReader - attr_reader :metric_store + attr_reader :exporters - def initialize - @metric_store = OpenTelemetry::SDK::Metrics::State::MetricStore.new + def initialize(exporter: nil) + @mutex = Mutex.new + @exporters = [] + register_exporter(exporter: exporter) end - def collect - @metric_store.collect + # The metrics Reader implementation supports registering metric Exporters + def register_exporter(exporter: nil) + return unless exporter.respond_to?(:pull) + + @mutex.synchronize do + @exporters << exporter + end + end + + # exporter pull should trigger exporter to send out the metrics + def collect(timeout: nil) + @exporters.each { |exporter| exporter.pull(timeout: timeout) if exporter.respond_to?(:pull) } + end + alias pull collect + + # The metrics Reader implementation supports configuring the + # default aggregation on the basis of instrument kind. + def aggregator(aggregator: nil, instrument_kind: nil) + return if aggregator.nil? + + @exporters.each do |exporter| + exporter.metric_store.metric_streams.each do |ms| + ms.default_aggregation = aggregator if instrument_kind.nil? || ms.instrument_kind == instrument_kind + end + end + end + + # The metrics Reader implementation supports configuring the + # default temporality on the basis of instrument kind. + def temporality(temporality: nil, instrument_kind: nil) + return if temporality.nil? + + @exporters.each do |exporter| + exporter.metric_store.metric_streams.each do |ms| + ms.default_aggregation.aggregation_temporality = temporality if instrument_kind.nil? || ms.instrument_kind == instrument_kind + end + end end + # shutdown all exporters def shutdown(timeout: nil) + @exporters.each { |exporter| exporter.shutdown(timeout: timeout) if exporter.respond_to?(:shutdown) } Export::SUCCESS + rescue StandardError + Export::FAILURE end + # force flush all exporters def force_flush(timeout: nil) + @exporters.each { |exporter| exporter.force_flush(timeout: timeout) if exporter.respond_to?(:force_flush) } Export::SUCCESS + rescue StandardError + Export::FAILURE end end end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/periodic_metric_reader.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/periodic_metric_reader.rb index 948f98976c..97ccdd84b5 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/export/periodic_metric_reader.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/export/periodic_metric_reader.rb @@ -25,14 +25,12 @@ class PeriodicMetricReader < MetricReader def initialize(export_interval_millis: Float(ENV.fetch('OTEL_METRIC_EXPORT_INTERVAL', 60_000)), export_timeout_millis: Float(ENV.fetch('OTEL_METRIC_EXPORT_TIMEOUT', 30_000)), exporter: nil) - super() + super(exporter: exporter) @export_interval = export_interval_millis / 1000.0 @export_timeout = export_timeout_millis / 1000.0 - @exporter = exporter @thread = nil @continue = false - @mutex = Mutex.new @export_mutex = Mutex.new start @@ -44,26 +42,21 @@ def shutdown(timeout: nil) @thread end thread&.join(@export_interval) - @exporter.force_flush if @exporter.respond_to?(:force_flush) - @exporter.shutdown - Export::SUCCESS + super(timeout: timeout) rescue StandardError => e OpenTelemetry.handle_error(exception: e, message: 'Fail to shutdown PeriodicMetricReader.') Export::FAILURE end def force_flush(timeout: nil) - export(timeout: timeout) - Export::SUCCESS - rescue StandardError - Export::FAILURE + super(timeout: timeout) end private def start @continue = true - if @exporter.nil? + if @exporters.empty? OpenTelemetry.logger.warn 'Missing exporter in PeriodicMetricReader.' elsif @thread&.alive? OpenTelemetry.logger.warn 'PeriodicMetricReader is still running. Please shutdown it if it needs to restart.' @@ -85,8 +78,7 @@ def start def export(timeout: nil) @export_mutex.synchronize do - collected_metrics = collect - @exporter.export(collected_metrics, timeout: timeout || @export_timeout) unless collected_metrics.empty? + @exporters.each { |exporter| exporter.pull(timeout: timeout || @export_timeout) if exporter.respond_to?(:pull) } end end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb index dee8fea8d2..a85e7154d7 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb @@ -31,7 +31,9 @@ def initialize(name, version, meter_provider) # @api private def add_metric_reader(metric_reader) @instrument_registry.each_value do |instrument| - instrument.register_with_new_metric_store(metric_reader.metric_store) + metric_reader.exporters.each do |exporter| + instrument.register_with_new_metric_store(exporter.metric_store) + end end end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/meter_provider.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/meter_provider.rb index 4538a88db4..2ced47279f 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/meter_provider.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/meter_provider.rb @@ -122,7 +122,9 @@ def add_metric_reader(metric_reader) def register_synchronous_instrument(instrument) @mutex.synchronize do @metric_readers.each do |mr| - instrument.register_with_new_metric_store(mr.metric_store) + mr.exporters.each do |exporter| + instrument.register_with_new_metric_store(exporter.metric_store) + end end end end diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_store.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_store.rb index b89eb09161..6d7ac5bb5b 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_store.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_store.rb @@ -13,6 +13,8 @@ module State # The MetricStore module provides SDK internal functionality that is not a part of the # public API. class MetricStore + attr_reader :metric_streams + def initialize @mutex = Mutex.new @epoch_start_time = now_in_nano @@ -23,7 +25,6 @@ def initialize def collect @mutex.synchronize do @epoch_end_time = now_in_nano - # snapshot = @metric_streams.map { |ms| ms.collect(@epoch_start_time, @epoch_end_time) } snapshot = @metric_streams.flat_map { |ms| ms.collect(@epoch_start_time, @epoch_end_time) } @epoch_start_time = @epoch_end_time snapshot diff --git a/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_stream.rb b/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_stream.rb index 05033f522c..d5aaf47416 100644 --- a/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_stream.rb +++ b/metrics_sdk/lib/opentelemetry/sdk/metrics/state/metric_stream.rb @@ -14,6 +14,7 @@ module State # public API. class MetricStream attr_reader :name, :description, :unit, :instrument_kind, :instrumentation_scope, :data_points + attr_accessor :default_aggregation def initialize( name, diff --git a/metrics_sdk/test/integration/in_memory_metric_pull_exporter_test.rb b/metrics_sdk/test/integration/in_memory_metric_pull_exporter_test.rb index 3e060e79dc..18f26b55f5 100644 --- a/metrics_sdk/test/integration/in_memory_metric_pull_exporter_test.rb +++ b/metrics_sdk/test/integration/in_memory_metric_pull_exporter_test.rb @@ -14,7 +14,8 @@ OpenTelemetry::SDK.configure metric_exporter = OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + metric_reader = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) meter = OpenTelemetry.meter_provider.meter('test') counter = meter.create_counter('counter', unit: 'smidgen', description: 'a small amount of something') @@ -25,7 +26,7 @@ counter.add(3, attributes: { 'b' => 'c' }) counter.add(4, attributes: { 'd' => 'e' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot).wont_be_empty diff --git a/metrics_sdk/test/integration/metric_exporter_test.rb b/metrics_sdk/test/integration/metric_exporter_test.rb new file mode 100644 index 0000000000..f93036da3b --- /dev/null +++ b/metrics_sdk/test/integration/metric_exporter_test.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative '../test_helper' + +describe OpenTelemetry::SDK do + describe '#metric_exporter' do + export = OpenTelemetry::SDK::Metrics::Export + let(:exporter) { export::MetricExporter.new } + + it 'verify basic exporter function' do + _(exporter.export(nil)).must_equal export::SUCCESS + _(exporter.shutdown).must_equal export::SUCCESS + _(exporter.force_flush).must_equal export::SUCCESS + _(exporter.collect).must_equal [] + end + end +end diff --git a/metrics_sdk/test/integration/metric_reader_test.rb b/metrics_sdk/test/integration/metric_reader_test.rb new file mode 100644 index 0000000000..db506dbc07 --- /dev/null +++ b/metrics_sdk/test/integration/metric_reader_test.rb @@ -0,0 +1,92 @@ +# frozen_string_literal: true + +# Copyright The OpenTelemetry Authors +# +# SPDX-License-Identifier: Apache-2.0 + +require_relative '../test_helper' + +describe OpenTelemetry::SDK do + describe '#metric_reader' do + export = OpenTelemetry::SDK::Metrics::Export + let(:exporter) { export::ConsoleMetricPullExporter.new } + + before do + reset_metrics_sdk + ENV['OTEL_METRICS_EXPORTER'] = 'none' + + @metric_reader = export::MetricReader.new(exporter: exporter) + + OpenTelemetry::SDK.configure + OpenTelemetry.meter_provider.add_metric_reader(@metric_reader) + + meter = OpenTelemetry.meter_provider.meter('test_1') + @counter = meter.create_counter('counter_1', unit: 'smidgen', description: 'a small amount of something') + end + + after do + ENV.delete('OTEL_METRICS_EXPORTER') + end + + it 'initialize metric_reader' do + metric_reader = export::MetricReader.new(exporter: exporter) + _(metric_reader.exporters.first.class).must_equal export::ConsoleMetricPullExporter + end + + it 'register additional metric_exporter' do + metric_reader = export::MetricReader.new(exporter: exporter) + in_memory_exporter = export::InMemoryMetricPullExporter.new + metric_reader.register_exporter(exporter: in_memory_exporter) + _(metric_reader.exporters[0].class).must_equal export::ConsoleMetricPullExporter + _(metric_reader.exporters[1].class).must_equal export::InMemoryMetricPullExporter + end + + it 'change default aggregator' do + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Sum + _(default_aggregation.aggregation_temporality).must_equal :delta + + @metric_reader.aggregator(aggregator: OpenTelemetry::SDK::Metrics::Aggregation::Drop.new) + + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Drop + end + + it 'do not change default aggregator if different instrument kind' do + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Sum + _(default_aggregation.aggregation_temporality).must_equal :delta + + @metric_reader.aggregator(aggregator: OpenTelemetry::SDK::Metrics::Aggregation::Drop.new, instrument_kind: :gauge) + + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Sum + end + + it 'change default aggregation_temporality' do + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Sum + _(default_aggregation.aggregation_temporality).must_equal :delta + + @metric_reader.temporality(temporality: :cumulative) + + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + _(default_aggregation.aggregation_temporality).must_equal :cumulative + end + + it 'do not change default aggregation_temporality if different instrument kind' do + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + + _(default_aggregation.class).must_equal OpenTelemetry::SDK::Metrics::Aggregation::Sum + _(default_aggregation.aggregation_temporality).must_equal :delta + + @metric_reader.temporality(temporality: :cumulative, instrument_kind: :gauge) + + default_aggregation = @counter.instance_variable_get(:@metric_streams).first.default_aggregation + _(default_aggregation.aggregation_temporality).must_equal :delta + end + end +end diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/configuration_patch_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/configuration_patch_test.rb index 88cd4bdaa0..437db2eeb1 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/configuration_patch_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/configuration_patch_test.rb @@ -44,7 +44,7 @@ reader = OpenTelemetry.meter_provider.metric_readers[0] assert_instance_of OpenTelemetry::SDK::Metrics::Export::PeriodicMetricReader, reader - assert_instance_of OpenTelemetry::Exporter::OTLP::Metrics::MetricsExporter, reader.instance_variable_get(:@exporter) + assert_instance_of OpenTelemetry::Exporter::OTLP::Metrics::MetricsExporter, reader.exporters.first end it 'can be set by environment variable' do @@ -57,7 +57,7 @@ reader = OpenTelemetry.meter_provider.metric_readers[0] assert_instance_of OpenTelemetry::SDK::Metrics::Export::PeriodicMetricReader, reader - assert_instance_of OpenTelemetry::SDK::Metrics::Export::ConsoleMetricPullExporter, reader.instance_variable_get(:@exporter) + assert_instance_of OpenTelemetry::SDK::Metrics::Export::ConsoleMetricPullExporter, reader.exporters.first end it 'supports "none" as an environment variable' do @@ -83,9 +83,9 @@ reader2 = OpenTelemetry.meter_provider.metric_readers[1] assert_instance_of OpenTelemetry::SDK::Metrics::Export::PeriodicMetricReader, reader1 - assert_instance_of OpenTelemetry::SDK::Metrics::Export::ConsoleMetricPullExporter, reader1.instance_variable_get(:@exporter) + assert_instance_of OpenTelemetry::SDK::Metrics::Export::ConsoleMetricPullExporter, reader1.exporters.first - assert_instance_of OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter, reader2 + assert_instance_of OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter, reader2.exporters.first end it 'defaults to noop with invalid env var' do diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/counter_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/counter_test.rb index ff5c3edfe2..289f25b3d6 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/counter_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/counter_test.rb @@ -8,18 +8,19 @@ describe OpenTelemetry::SDK::Metrics::Instrument::Counter do let(:metric_exporter) { OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new } + let(:metric_reader) { OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) } let(:meter) { OpenTelemetry.meter_provider.meter('test') } let(:counter) { meter.create_counter('counter', unit: 'smidgen', description: 'a small amount of something') } before do reset_metrics_sdk OpenTelemetry::SDK.configure - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) end it 'counts' do counter.add(1, attributes: { 'foo' => 'bar' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].name).must_equal('counter') diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/gauge_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/gauge_test.rb index f3fc5509c6..76c60cefc0 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/gauge_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/gauge_test.rb @@ -8,18 +8,19 @@ describe OpenTelemetry::SDK::Metrics::Instrument::Gauge do let(:metric_exporter) { OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new } + let(:metric_reader) { OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) } let(:meter) { OpenTelemetry.meter_provider.meter('test') } let(:gauge) { meter.create_gauge('gauge', unit: 'smidgen', description: 'a small amount of something') } before do reset_metrics_sdk OpenTelemetry::SDK.configure - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) end it 'gauge should count -2' do gauge.record(-2, attributes: { 'foo' => 'bar' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].name).must_equal('gauge') @@ -34,7 +35,7 @@ it 'gauge should count 1 for last recording' do gauge.record(-2, attributes: { 'foo' => 'bar' }) gauge.record(1, attributes: { 'foo' => 'bar' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot.size).must_equal(1) @@ -48,7 +49,7 @@ gauge2 = meter.create_gauge('gauge2', unit: 'smidgen', description: 'a small amount of something') gauge2.record(10, attributes: {}) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot.size).must_equal(2) diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/histogram_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/histogram_test.rb index 771ffaef83..65d7ce48a0 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/histogram_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/histogram_test.rb @@ -8,19 +8,20 @@ describe OpenTelemetry::SDK::Metrics::Instrument::Histogram do let(:metric_exporter) { OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new } + let(:metric_reader) { OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) } let(:meter) { OpenTelemetry.meter_provider.meter('test') } let(:histogram) { meter.create_histogram('histogram', unit: 'smidgen', description: 'a small amount of something') } before do reset_metrics_sdk OpenTelemetry::SDK.configure - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) end it 'histograms' do histogram.record(5, attributes: { 'foo' => 'bar' }) histogram.record(6, attributes: { 'foo' => 'bar' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].name).must_equal('histogram') diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/up_down_counter_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/up_down_counter_test.rb index 687ad27a89..3a6ddca642 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/up_down_counter_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/instrument/up_down_counter_test.rb @@ -8,19 +8,20 @@ describe OpenTelemetry::SDK::Metrics::Instrument::UpDownCounter do let(:metric_exporter) { OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new } + let(:metric_reader) { OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) } let(:meter) { OpenTelemetry.meter_provider.meter('test') } let(:up_down_counter) { meter.create_up_down_counter('up_down_counter', unit: 'smidgen', description: 'a small amount of something') } before do reset_metrics_sdk OpenTelemetry::SDK.configure - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) end it 'counts up and down' do up_down_counter.add(1, attributes: { 'foo' => 'bar' }) up_down_counter.add(-2, attributes: { 'foo' => 'bar' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].name).must_equal('up_down_counter') diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/meter_provider_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/meter_provider_test.rb index 72f04e08c9..83e72daf65 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/meter_provider_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/meter_provider_test.rb @@ -112,29 +112,33 @@ it 'associates the metric store with instruments created before the metric reader' do meter_a = OpenTelemetry.meter_provider.meter('a').create_counter('meter_a') - metric_reader_a = OpenTelemetry::SDK::Metrics::Export::MetricReader.new + metric_exporter_a = OpenTelemetry::SDK::Metrics::Export::MetricExporter.new + metric_reader_a = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter_a) OpenTelemetry.meter_provider.add_metric_reader(metric_reader_a) - metric_reader_b = OpenTelemetry::SDK::Metrics::Export::MetricReader.new + metric_exporter_b = OpenTelemetry::SDK::Metrics::Export::MetricExporter.new + metric_reader_b = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter_b) OpenTelemetry.meter_provider.add_metric_reader(metric_reader_b) _(meter_a.instance_variable_get(:@metric_streams).size).must_equal(2) - _(metric_reader_a.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) - _(metric_reader_b.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) + _(metric_reader_a.exporters.first.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) + _(metric_reader_b.exporters.first.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) end it 'associates the metric store with instruments created after the metric reader' do - metric_reader_a = OpenTelemetry::SDK::Metrics::Export::MetricReader.new + metric_exporter_a = OpenTelemetry::SDK::Metrics::Export::MetricExporter.new + metric_reader_a = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter_a) OpenTelemetry.meter_provider.add_metric_reader(metric_reader_a) - metric_reader_b = OpenTelemetry::SDK::Metrics::Export::MetricReader.new + metric_exporter_b = OpenTelemetry::SDK::Metrics::Export::MetricExporter.new + metric_reader_b = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter_b) OpenTelemetry.meter_provider.add_metric_reader(metric_reader_b) meter_a = OpenTelemetry.meter_provider.meter('a').create_counter('meter_a') _(meter_a.instance_variable_get(:@metric_streams).size).must_equal(2) - _(metric_reader_a.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) - _(metric_reader_b.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) + _(metric_reader_a.exporters.first.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) + _(metric_reader_b.exporters.first.metric_store.instance_variable_get(:@metric_streams).size).must_equal(1) end end diff --git a/metrics_sdk/test/opentelemetry/sdk/metrics/view/registered_view_test.rb b/metrics_sdk/test/opentelemetry/sdk/metrics/view/registered_view_test.rb index 4638485777..fb70f5119e 100644 --- a/metrics_sdk/test/opentelemetry/sdk/metrics/view/registered_view_test.rb +++ b/metrics_sdk/test/opentelemetry/sdk/metrics/view/registered_view_test.rb @@ -14,7 +14,8 @@ OpenTelemetry::SDK.configure metric_exporter = OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + metric_reader = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) meter = OpenTelemetry.meter_provider.meter('test') OpenTelemetry.meter_provider.add_view('counter', aggregation: ::OpenTelemetry::SDK::Metrics::Aggregation::Drop.new) @@ -24,7 +25,7 @@ counter.add(1) counter.add(2, attributes: { 'a' => 'b' }) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot).wont_be_empty @@ -47,7 +48,8 @@ OpenTelemetry::SDK.configure metric_exporter = OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + metric_reader = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) meter = OpenTelemetry.meter_provider.meter('test') OpenTelemetry.meter_provider.add_view('counter', aggregation: ::OpenTelemetry::SDK::Metrics::Aggregation::LastValue.new) @@ -59,7 +61,7 @@ counter.add(3) counter.add(4) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].data_points).wont_be_empty @@ -70,7 +72,8 @@ OpenTelemetry::SDK.configure metric_exporter = OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new - OpenTelemetry.meter_provider.add_metric_reader(metric_exporter) + metric_reader = OpenTelemetry::SDK::Metrics::Export::MetricReader.new(exporter: metric_exporter) + OpenTelemetry.meter_provider.add_metric_reader(metric_reader) meter = OpenTelemetry.meter_provider.meter('test') OpenTelemetry.meter_provider.add_view('retnuoc', aggregation: ::OpenTelemetry::SDK::Metrics::Aggregation::LastValue.new) @@ -82,7 +85,7 @@ counter.add(3) counter.add(4) - metric_exporter.pull + metric_reader.pull last_snapshot = metric_exporter.metric_snapshots _(last_snapshot[0].data_points).wont_be_empty