From 7eb0fbc6c4a292d92272ca5b2448d1e2a2ec2937 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Fri, 26 Sep 2025 12:05:14 +0200 Subject: [PATCH] Deprecate metrics --- CHANGELOG.md | 22 +++++++++ sentry-ruby/lib/sentry/configuration.rb | 2 +- sentry-ruby/lib/sentry/metrics.rb | 12 +++++ .../lib/sentry/metrics/configuration.rb | 14 +++++- .../spec/sentry/metrics/configuration_spec.rb | 15 ++++++ sentry-ruby/spec/sentry/metrics_spec.rb | 49 +++++++++++++++++-- 6 files changed, 108 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69f0d1d41..ba9437492 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,28 @@ - Auto-enable Rails structured logging when `enable_logs` is true ([#2721](https://github.com/getsentry/sentry-ruby/pull/2721)) +### Miscellaneous + +- Deprecate all Metrics related APIs [#2726](https://github.com/getsentry/sentry-ruby/pull/2726) + + Sentry [no longer has the Metrics Beta offering](https://sentry.zendesk.com/hc/en-us/articles/26369339769883-Metrics-Beta-Ended-on-October-7th) so + all the following APIs linked to Metrics have been deprecated and will be removed in the next major. + + ```ruby + Sentry.init do |config| + # ... + config.metrics.enabled = true + config.metrics.enable_code_locations = true + config.metrics.before_emit = lambda {} + end + + Sentry::Metrics.increment('button_click') + Sentry::Metrics.distribution('page_load', 15.0, unit: 'millisecond') + Sentry::Metrics.gauge('page_load', 15.0, unit: 'millisecond') + Sentry::Metrics.set('user_view', 'jane') + Sentry::Metrics.timing('how_long') { sleep(1) } + ``` + ### Internal - Fix leftover `config.logger` call in `graphql` patch ([#2722](https://github.com/getsentry/sentry-ruby/2722) diff --git a/sentry-ruby/lib/sentry/configuration.rb b/sentry-ruby/lib/sentry/configuration.rb index 7a93cea1a..325134eab 100644 --- a/sentry-ruby/lib/sentry/configuration.rb +++ b/sentry-ruby/lib/sentry/configuration.rb @@ -512,7 +512,7 @@ def initialize @transport = Transport::Configuration.new @cron = Cron::Configuration.new - @metrics = Metrics::Configuration.new + @metrics = Metrics::Configuration.new(self.sdk_logger) @structured_logging = StructuredLoggingConfiguration.new @gem_specs = Hash[Gem::Specification.map { |spec| [spec.name, spec.version.to_s] }] if Gem::Specification.respond_to?(:map) diff --git a/sentry-ruby/lib/sentry/metrics.rb b/sentry-ruby/lib/sentry/metrics.rb index bcab324f4..5da299605 100644 --- a/sentry-ruby/lib/sentry/metrics.rb +++ b/sentry-ruby/lib/sentry/metrics.rb @@ -19,22 +19,28 @@ module Metrics class << self def increment(key, value = 1.0, unit: "none", tags: {}, timestamp: nil) + log_deprecation Sentry.metrics_aggregator&.add(:c, key, value, unit: unit, tags: tags, timestamp: timestamp) end def distribution(key, value, unit: "none", tags: {}, timestamp: nil) + log_deprecation Sentry.metrics_aggregator&.add(:d, key, value, unit: unit, tags: tags, timestamp: timestamp) end def set(key, value, unit: "none", tags: {}, timestamp: nil) + log_deprecation Sentry.metrics_aggregator&.add(:s, key, value, unit: unit, tags: tags, timestamp: timestamp) end def gauge(key, value, unit: "none", tags: {}, timestamp: nil) + log_deprecation Sentry.metrics_aggregator&.add(:g, key, value, unit: unit, tags: tags, timestamp: timestamp) end def timing(key, unit: "second", tags: {}, timestamp: nil, &block) + log_deprecation + return unless block_given? return yield unless DURATION_UNITS.include?(unit) @@ -51,6 +57,12 @@ def timing(key, unit: "second", tags: {}, timestamp: nil, &block) Sentry.metrics_aggregator&.add(:d, key, value, unit: unit, tags: tags, timestamp: timestamp) result end + + def log_deprecation + Sentry.sdk_logger.warn(LOGGER_PROGNAME) do + "`Sentry::Metrics` is now deprecated and will be removed in the next major." + end + end end end end diff --git a/sentry-ruby/lib/sentry/metrics/configuration.rb b/sentry-ruby/lib/sentry/metrics/configuration.rb index 84681f31e..2e93bf3f0 100644 --- a/sentry-ruby/lib/sentry/metrics/configuration.rb +++ b/sentry-ruby/lib/sentry/metrics/configuration.rb @@ -4,12 +4,13 @@ module Sentry module Metrics class Configuration include ArgumentCheckingHelper + include LoggingHelper # Enable metrics usage. # Starts a new {Sentry::Metrics::Aggregator} instance to aggregate metrics # and a thread to aggregate flush every 5 seconds. # @return [Boolean] - attr_accessor :enabled + attr_reader :enabled # Enable code location reporting. # Will be sent once per day. @@ -32,11 +33,20 @@ class Configuration # @return [Proc, nil] attr_reader :before_emit - def initialize + def initialize(sdk_logger) + @sdk_logger = sdk_logger @enabled = false @enable_code_locations = true end + def enabled=(value) + log_warn <<~MSG + `config.metrics` is now deprecated and will be removed in the next major. + MSG + + @enabled = value + end + def before_emit=(value) check_callable!("metrics.before_emit", value) diff --git a/sentry-ruby/spec/sentry/metrics/configuration_spec.rb b/sentry-ruby/spec/sentry/metrics/configuration_spec.rb index c4bd7d430..ca7e7f9e6 100644 --- a/sentry-ruby/spec/sentry/metrics/configuration_spec.rb +++ b/sentry-ruby/spec/sentry/metrics/configuration_spec.rb @@ -1,6 +1,21 @@ # frozen_string_literal: true RSpec.describe Sentry::Metrics::Configuration do + let(:string_io) { StringIO.new } + let(:sdk_logger) { Logger.new(string_io) } + + let(:subject) { described_class.new(sdk_logger) } + + describe '#enabled=' do + it 'logs deprecation warning' do + subject.enabled = true + + expect(string_io.string).to include( + "WARN -- sentry: `config.metrics` is now deprecated and will be removed in the next major." + ) + end + end + describe '#before_emit=' do it 'raises error when setting before_emit to anything other than callable or nil' do subject.before_emit = -> { } diff --git a/sentry-ruby/spec/sentry/metrics_spec.rb b/sentry-ruby/spec/sentry/metrics_spec.rb index 4aba80417..bca1aa196 100644 --- a/sentry-ruby/spec/sentry/metrics_spec.rb +++ b/sentry-ruby/spec/sentry/metrics_spec.rb @@ -1,15 +1,18 @@ # frozen_string_literal: true RSpec.describe Sentry::Metrics do + let(:aggregator) { Sentry.metrics_aggregator } + let(:fake_time) { Time.new(2024, 1, 1, 1, 1, 3) } + let(:string_io) { StringIO.new } + let(:sdk_logger) { Logger.new(string_io) } + before do perform_basic_setup do |config| config.metrics.enabled = true + config.sdk_logger = sdk_logger end end - let(:aggregator) { Sentry.metrics_aggregator } - let(:fake_time) { Time.new(2024, 1, 1, 1, 1, 3) } - describe '.increment' do it 'passes default value of 1.0 with only key' do expect(aggregator).to receive(:add).with( @@ -36,6 +39,14 @@ described_class.increment('foo', 5.0, unit: 'second', tags: { fortytwo: 42 }, timestamp: fake_time) end + + it 'logs deprecation warning' do + described_class.increment('foo') + + expect(string_io.string).to include( + "WARN -- sentry: `Sentry::Metrics` is now deprecated and will be removed in the next major." + ) + end end describe '.distribution' do @@ -51,6 +62,14 @@ described_class.distribution('foo', 5.0, unit: 'second', tags: { fortytwo: 42 }, timestamp: fake_time) end + + it 'logs deprecation warning' do + described_class.distribution('foo', 5.0, unit: 'second', tags: { fortytwo: 42 }, timestamp: fake_time) + + expect(string_io.string).to include( + "WARN -- sentry: `Sentry::Metrics` is now deprecated and will be removed in the next major." + ) + end end describe '.set' do @@ -66,6 +85,14 @@ described_class.set('foo', 'jane', tags: { fortytwo: 42 }, timestamp: fake_time) end + + it 'logs deprecation warning' do + described_class.set('foo', 'jane', tags: { fortytwo: 42 }, timestamp: fake_time) + + expect(string_io.string).to include( + "WARN -- sentry: `Sentry::Metrics` is now deprecated and will be removed in the next major." + ) + end end describe '.gauge' do @@ -81,6 +108,14 @@ described_class.gauge('foo', 5.0, unit: 'second', tags: { fortytwo: 42 }, timestamp: fake_time) end + + it 'logs deprecation warning' do + described_class.gauge('foo', 5.0, unit: 'second', tags: { fortytwo: 42 }, timestamp: fake_time) + + expect(string_io.string).to include( + "WARN -- sentry: `Sentry::Metrics` is now deprecated and will be removed in the next major." + ) + end end describe '.timing' do @@ -109,6 +144,14 @@ expect(result).to eq(42) end + it 'logs deprecation warning' do + described_class.timing('foo', unit: 'millisecond', tags: { fortytwo: 42 }, timestamp: fake_time) { sleep(0.1); 42 } + + expect(string_io.string).to include( + "WARN -- sentry: `Sentry::Metrics` is now deprecated and will be removed in the next major." + ) + end + context 'with running transaction' do let(:transaction) { transaction = Sentry.start_transaction(name: 'metrics') }