Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add synchronous gauge #1718

Merged
merged 17 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def initialize(kind, name, unit, desc, callable)

def upgrade_with(meter)
@delegate = case @kind
when :counter, :histogram, :up_down_counter
when :counter, :histogram, :up_down_counter, :gauge
meter.send("create_#{@kind}", @name, unit: @unit, description: @desc)
when :observable_counter, :observable_gauge, :observable_up_down_counter
meter.send("create_#{@kind}", @name, unit: @unit, description: @desc, callback: @callback)
Expand Down
1 change: 1 addition & 0 deletions metrics_api/lib/opentelemetry/internal/proxy_meter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ def create_instrument(kind, name, unit, description, callback)
case kind
when :counter then @delegate.create_counter(name, unit: unit, description: description)
when :histogram then @delegate.create_histogram(name, unit: unit, description: description)
when :gauge then @delegate.create_gauge(name, unit: unit, description: description)
when :up_down_counter then @delegate.create_up_down_counter(name, unit: unit, description: description)
when :observable_counter then @delegate.create_observable_counter(name, unit: unit, description: description, callback: callback)
when :observable_gauge then @delegate.create_observable_gauge(name, unit: unit, description: description, callback: callback)
Expand Down
1 change: 1 addition & 0 deletions metrics_api/lib/opentelemetry/metrics/instrument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

require 'opentelemetry/metrics/instrument/counter'
require 'opentelemetry/metrics/instrument/histogram'
require 'opentelemetry/metrics/instrument/gauge'
require 'opentelemetry/metrics/instrument/observable_counter'
require 'opentelemetry/metrics/instrument/observable_gauge'
require 'opentelemetry/metrics/instrument/observable_up_down_counter'
Expand Down
23 changes: 23 additions & 0 deletions metrics_api/lib/opentelemetry/metrics/instrument/gauge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module Metrics
module Instrument
# No-op implementation of UpDownCounter.
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
class Gauge
# Increment or decrement the UpDownCounter by a fixed amount.
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
#
# @param [Numeric] amount The amount to be added, can be positive, negative or zero.
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
# @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
# Values must be non-nil and (array of) string, boolean or numeric type.
# Array values must not contain nil elements and all elements must be of
# the same basic type (string, numeric, boolean).
def record(amount, attributes: {}); end
end
end
end
end
7 changes: 6 additions & 1 deletion metrics_api/lib/opentelemetry/metrics/meter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ class Meter
COUNTER = Instrument::Counter.new
OBSERVABLE_COUNTER = Instrument::ObservableCounter.new
HISTOGRAM = Instrument::Histogram.new
GAUGE = Instrument::Gauge.new
OBSERVABLE_GAUGE = Instrument::ObservableGauge.new
UP_DOWN_COUNTER = Instrument::UpDownCounter.new
OBSERVABLE_UP_DOWN_COUNTER = Instrument::ObservableUpDownCounter.new

NAME_REGEX = /\A[a-zA-Z][-.\w]{0,62}\z/

private_constant(:COUNTER, :OBSERVABLE_COUNTER, :HISTOGRAM, :OBSERVABLE_GAUGE, :UP_DOWN_COUNTER, :OBSERVABLE_UP_DOWN_COUNTER)
private_constant(:COUNTER, :OBSERVABLE_COUNTER, :HISTOGRAM, :GAUGE, :OBSERVABLE_GAUGE, :UP_DOWN_COUNTER, :OBSERVABLE_UP_DOWN_COUNTER)

DuplicateInstrumentError = Class.new(OpenTelemetry::Error)
InstrumentNameError = Class.new(OpenTelemetry::Error)
Expand All @@ -37,6 +38,10 @@ def create_histogram(name, unit: nil, description: nil)
create_instrument(:histogram, name, unit, description, nil) { HISTOGRAM }
end

def create_gauge(name, unit: nil, description: nil)
create_instrument(:gauge, name, unit, description, nil) { GAUGE }
end
kaylareopelle marked this conversation as resolved.
Show resolved Hide resolved

def create_up_down_counter(name, unit: nil, description: nil)
create_instrument(:up_down_counter, name, unit, description, nil) { UP_DOWN_COUNTER }
end
Expand Down
1 change: 1 addition & 0 deletions metrics_sdk/lib/opentelemetry/sdk/metrics/instrument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ module Instrument
require 'opentelemetry/sdk/metrics/instrument/observable_gauge'
require 'opentelemetry/sdk/metrics/instrument/observable_up_down_counter'
require 'opentelemetry/sdk/metrics/instrument/up_down_counter'
require 'opentelemetry/sdk/metrics/instrument/gauge'
48 changes: 48 additions & 0 deletions metrics_sdk/lib/opentelemetry/sdk/metrics/instrument/gauge.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

module OpenTelemetry
module SDK
module Metrics
module Instrument
# {Gauge} is the SDK implementation of {OpenTelemetry::Metrics::Gauge}.
class Gauge < OpenTelemetry::SDK::Metrics::Instrument::SynchronousInstrument
# Returns the instrument kind as a Symbol
#
# @return [Symbol]
def instrument_kind
:gauge
end

# Increment or decremt the Gauge by a fixed amount.
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
#
# @param [numeric] increment The increment amount, which MUST be a non-negative numeric value.
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
# @param [Hash{String => String, Numeric, Boolean, Array<String, Numeric, Boolean>}] attributes
# Values must be non-nil and (array of) string, boolean or numeric type.
# Array values must not contain nil elements and all elements must be of
# the same basic type (string, numeric, boolean).
def record(amount, attributes: {})
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
# TODO: When the metrics SDK stabilizes and is merged into the main SDK,
# we can leverage the SDK Internal validation classes to enforce this:
# https://github.com/open-telemetry/opentelemetry-ruby/blob/6bec625ef49004f364457c26263df421526b60d6/sdk/lib/opentelemetry/sdk/internal.rb#L47
Comment on lines +28 to +30
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we turn this TODO into an issue, or reference it on an existing issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, I will create an issue to track it (e.g. something like integrate metrics_sdk to sdk?)

Copy link
Contributor

Choose a reason for hiding this comment

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

Just seeing this! Yes, I think something like that would work and add a link to this code for reference. This is a good example for a similar TODO for logs: #1739

update(amount, attributes)
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
nil
rescue StandardError => e
OpenTelemetry.handle_error(exception: e)
nil
end

private

# TODO: replace the default aggregation to LastValue
xuan-cao-swi marked this conversation as resolved.
Show resolved Hide resolved
def default_aggregation
OpenTelemetry::SDK::Metrics::Aggregation::Sum.new
end
end
end
end
end
end
1 change: 1 addition & 0 deletions metrics_sdk/lib/opentelemetry/sdk/metrics/meter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def create_instrument(kind, name, unit, description, callback)
case kind
when :counter then OpenTelemetry::SDK::Metrics::Instrument::Counter.new(name, unit, description, @instrumentation_scope, @meter_provider)
when :observable_counter then OpenTelemetry::SDK::Metrics::Instrument::ObservableCounter.new(name, unit, description, callback, @instrumentation_scope, @meter_provider)
when :gauge then OpenTelemetry::SDK::Metrics::Instrument::Gauge.new(name, unit, description, @instrumentation_scope, @meter_provider)
when :histogram then OpenTelemetry::SDK::Metrics::Instrument::Histogram.new(name, unit, description, @instrumentation_scope, @meter_provider)
when :observable_gauge then OpenTelemetry::SDK::Metrics::Instrument::ObservableGauge.new(name, unit, description, callback, @instrumentation_scope, @meter_provider)
when :up_down_counter then OpenTelemetry::SDK::Metrics::Instrument::UpDownCounter.new(name, unit, description, @instrumentation_scope, @meter_provider)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

# Copyright The OpenTelemetry Authors
#
# SPDX-License-Identifier: Apache-2.0

require 'test_helper'

describe OpenTelemetry::SDK::Metrics::Instrument::Gauge do
let(:metric_exporter) { OpenTelemetry::SDK::Metrics::Export::InMemoryMetricPullExporter.new }
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)
end

it 'gauge should count -2' do
gauge.record(-2, attributes: { 'foo' => 'bar' })
metric_exporter.pull
last_snapshot = metric_exporter.metric_snapshots.last

_(last_snapshot[0].name).must_equal('gauge')
_(last_snapshot[0].unit).must_equal('smidgen')
_(last_snapshot[0].description).must_equal('a small amount of something')
_(last_snapshot[0].instrumentation_scope.name).must_equal('test')
_(last_snapshot[0].data_points[0].attributes).must_equal('foo' => 'bar')
_(last_snapshot[0].data_points[0].value).must_equal(-2)
_(last_snapshot[0].aggregation_temporality).must_equal(:delta)
end
end
Loading