Skip to content
This repository has been archived by the owner on Sep 24, 2024. It is now read-only.

Conversation

elias19r
Copy link

@elias19r elias19r commented Jul 7, 2023

This PR is just for visibility.

The goal is to open this PR against main in open-telemetry/opentelemetry-ruby
after PR #1442 is merged.


  • Make Proxy Instrument classes inherit from API Instrument classes
  • Make SDK Instrument classes inherit from API Instrument classes
  • Add kind method to Instruments
  • Make Instruments have a reference to Meter
  • Make Meter have a reference to MeterProvider
  • Make Meter responsible for creating a MetricStream for an Instrument
    and MetricStore and for registering new instruments with existing MetricStreams
  • Add empty Aggregation::LastValue
  • Make Meter hold the definition of default aggregation for Instruments
  • Make Aggregation::Sum test cases more verbose with examples
  • Move InstrumentationScope creation to Meter on initialize
  • Add schema_url and attributes to InstrumentationScope (?)

@elias19r elias19r changed the title Adjust existing Metrics SDK to match changes to API Adjust existing Metrics SDK code to match changes to API Jul 7, 2023
Comment on lines +8 to +22
module Metrics
module ProxyInstrument
end
end
end

require 'opentelemetry/internal/proxy_instrument/delegate_synchronous_instrument'
require 'opentelemetry/internal/proxy_instrument/counter'
require 'opentelemetry/internal/proxy_instrument/histogram'
require 'opentelemetry/internal/proxy_instrument/up_down_counter'

require 'opentelemetry/internal/proxy_instrument/delegate_asynchronous_instrument'
require 'opentelemetry/internal/proxy_instrument/observable_counter'
require 'opentelemetry/internal/proxy_instrument/observable_gauge'
require 'opentelemetry/internal/proxy_instrument/observable_up_down_counter'
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to make Proxy Instruments inherit from API Instrument classes, I've created a Proxy Instrument class for each Instrument. They include the delegate= setter from a module.

Comment on lines -29 to +78
@mutex.synchronize do
@delegate_mutex.synchronize do
if @delegate.nil?
@delegate = meter
@instrument_registry.each_value { |instrument| instrument.upgrade_with(meter) }

@instrument_registry.each_value do |proxy_instrument|
proxy_instrument.delegate =
case proxy_instrument
when ProxyInstrument::Counter
meter.create_counter(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
advice: proxy_instrument.advice
)
when ProxyInstrument::Histogram
meter.create_histogram(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
advice: proxy_instrument.advice
)
when ProxyInstrument::UpDownCounter
meter.create_up_down_counter(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
advice: proxy_instrument.advice
)
when ProxyInstrument::ObservableCounter
meter.create_observable_counter(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
callbacks: proxy_instrument.callbacks
)
when ProxyInstrument::ObservableGauge
meter.create_observable_gauge(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
callbacks: proxy_instrument.callbacks
)
when ProxyInstrument::ObservableUpDownCounter
meter.create_observable_up_down_counter(
proxy_instrument.name,
unit: proxy_instrument.unit,
description: proxy_instrument.description,
callbacks: proxy_instrument.callbacks
)
end
end
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more verbose now because we have a Proxy Instrument class for each Instrument

Comment on lines +27 to 43
# @api private
def add_metric_stream(metric_stream)
@mutex.synchronize do
@metric_streams.push(metric_stream)
nil
end
end

private

def update(value, attributes)
@mutex.synchronize do
@metric_streams.each do |metric_stream|
metric_stream.update(value, attributes)
end
end
end
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved add_metric_reader and update to the API Instrument class.

The logic to create a MetricStream is in the Meter

Comment on lines +175 to 185
def register_instrument(name, instrument)
name = name.downcase

@mutex.synchronize do
if @instrument_registry.include?(name)
OpenTelemetry.logger.warn("duplicate instrument registration occurred for #{name}")
end

@instrument_registry[name] = yield
@instrument_registry[name] = instrument
end
end
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed create_instrument to register_instrument for clarity and I couldn't take advantage of using a block, so I've changed it to receive instrument as an argument.

@@ -11,41 +11,50 @@ 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
def initialize(aggregation_temporality: :delta)
attr_reader :aggregation_temporality, :monotonic
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added attr_reader :monotonic. It is not being used in the class. I think it will be used later when we collect a MetricStream, but I can't quite see the big picture yet

:counter
end

class Counter < OpenTelemetry::Metrics::Instrument::Counter
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made SDK Instrument classes inherit from API Instrument classes

Comment on lines -44 to -46
def default_aggregation
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new
end
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've moved the default aggregations definition to Meter because it uses them to create MetricStream there. Thinking again, leaving definitions in each instrument class may look better but it would have to be a public method.

Comment on lines -26 to +32
snapshot = @metric_streams.map { |ms| ms.collect(@epoch_start_time, @epoch_end_time) }
metric_data = @metric_streams.map do |metric_stream|
metric_stream.collect(@epoch_start_time, @epoch_end_time)
end
@epoch_start_time = @epoch_end_time
snapshot

metric_data
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just renamed snapshot to metric_data for a hint of the data type being returned

Comment on lines +10 to +15
InstrumentationScope = Struct.new(
:name,
:version,
:schema_url,
:attributes
)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Look up docs for why I added schema_url and attributes to InstrumentationScope 🤔

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant