From dc6b681f2d6946e4da8cfa0ed882ce9e9be93627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Hern=C3=A1ndez?= Date: Mon, 3 Aug 2026 17:17:31 +0200 Subject: [PATCH] Add OTel span attribute to deprecated endpoints (#40030) --- .../concerns/deprecation_concern.rb | 5 ++ .../concerns/deprecation_concern_spec.rb | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 spec/controllers/concerns/deprecation_concern_spec.rb diff --git a/app/controllers/concerns/deprecation_concern.rb b/app/controllers/concerns/deprecation_concern.rb index ad8de724a1c..b9c7d286f09 100644 --- a/app/controllers/concerns/deprecation_concern.rb +++ b/app/controllers/concerns/deprecation_concern.rb @@ -11,6 +11,11 @@ module DeprecationConcern before_action(**kwargs) do response.headers['Deprecation'] = deprecation_timestamp response.headers['Sunset'] = sunset if sunset + + span = OpenTelemetry::Trace.current_span + next unless span&.recording? + + span.set_attribute('app.endpoint.deprecated', true) end end end diff --git a/spec/controllers/concerns/deprecation_concern_spec.rb b/spec/controllers/concerns/deprecation_concern_spec.rb new file mode 100644 index 00000000000..d27f09da03d --- /dev/null +++ b/spec/controllers/concerns/deprecation_concern_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe DeprecationConcern do + render_views + + controller(ApplicationController) do + include DeprecationConcern # rubocop:disable RSpec/DescribedClass + + deprecate_api '2026-08-03', sunset: '2026-10-01' + + def deprecated + render plain: 'deprecated' + end + end + + before do + routes.draw do + get 'deprecated' => 'anonymous#deprecated' + end + end + + context 'with response headers' do + it 'adds Deprecation header' do + get :deprecated + + expect(response.body).to eq('deprecated') + expect(response.headers['Deprecation']).to eq('@1785715200') + end + + it 'adds Sunset header' do + get :deprecated + + expect(response.headers['Sunset']).to eq('Thu, 01 Oct 2026 00:00:00 GMT') + end + end + + context 'with OpenTelemetry traces' do + let(:span) { instance_double(OpenTelemetry::Trace::Span) } + + before do + allow(OpenTelemetry::Trace).to receive(:current_span).and_return(span) + allow(span).to receive(:recording?).and_return(true) + allow(span).to receive(:set_attribute) + end + + it 'adds a deprecation attribute request span' do + get :deprecated + + expect(span).to have_received(:set_attribute).with('app.endpoint.deprecated', true) + end + end +end