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

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
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?

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
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# TODO: replace the default aggregation to LastValue

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