Skip to content

Commit

Permalink
Merge pull request #19078 from department-of-veterans-affairs/aedara/…
Browse files Browse the repository at this point in the history
…APPEALS-26087

aedara/APPEALS-26087 Setup monitoring for deprecation warnings
  • Loading branch information
sbashamoni authored Aug 15, 2023
2 parents ec24584 + a645a40 commit 0e4fdbf
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
53 changes: 53 additions & 0 deletions config/initializers/deprecation_warning_subscriber.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# frozen_string_literal: true

# @note For use in conjuction with setting `Rails.application.config.active_support.deprecation = :notify`.
# Whenever a “deprecation.rails” notification is published, it will dispatch the event
# (ActiveSupport::Notifications::Event) to method #deprecation.
class DeprecationWarningSubscriber < ActiveSupport::Subscriber
APP_NAME = "caseflow"
SLACK_ALERT_CHANNEL = "#appeals-deprecation-alerts"

attach_to :rails

def deprecation(event)
emit_warning_to_application_logs(event)
emit_warning_to_sentry(event)
emit_warning_to_slack_alerts_channel(event)
rescue StandardError => error
Raven.capture_exception(error)
end

private

def emit_warning_to_application_logs(event)
Rails.logger.warn(event.payload[:message])
end

def emit_warning_to_sentry(event)
# Pre-emptive bugfix for future versions of the `sentry-raven` gem:
# Need to convert callstack elements from `Thread::Backtrace::Location` objects to `Strings`
# to avoid a `TypeError` on `options.deep_dup` in `Raven.capture_message`:
# https://github.com/getsentry/sentry-ruby/blob/2e07e0295ba83df4c76c7bf3315d199c7050a7f9/lib/raven/instance.rb#L114
callstack_strings = event.payload[:callstack].map(&:to_s)

Raven.capture_message(
event.payload[:message],
level: "warning",
extra: {
message: event.payload[:message],
gem_name: event.payload[:gem_name],
deprecation_horizon: event.payload[:deprecation_horizon],
callstack: callstack_strings,
environment: Rails.env
}
)
end

def emit_warning_to_slack_alerts_channel(event)
slack_alert_title = "Deprecation Warning - #{APP_NAME} (#{ENV['DEPLOY_ENV']})"

SlackService
.new(url: ENV["SLACK_DISPATCH_ALERT_URL"])
.send_notification(event.payload[:message], slack_alert_title, SLACK_ALERT_CHANNEL)
end
end
84 changes: 84 additions & 0 deletions spec/initializers/deprecation_warning_subscriber_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# frozen_string_literal: true

describe "DeprecationWarningSubscriber" do
let(:rails_logger) { Rails.logger }
let(:slack_service) { SlackService.new(url: "dummy-url") }

before do
allow(Rails).to receive(:logger).and_return(rails_logger)
allow(rails_logger).to receive(:warn)

allow(Raven).to receive(:capture_message)
allow(Raven).to receive(:capture_exception)

allow(SlackService).to receive(:new).with(url: anything).and_return(slack_service)
allow(slack_service).to receive(:send_notification)
end

context "when a 'deprecation.rails' event is instrumented" do
let(:app_name) { "caseflow" }
let(:deploy_env) { ENV["DEPLOY_ENV"] }
let(:payload) do
{
message: "test message",
gem_name: "Rails",
deprecation_horizon: "6.0",
callstack: [location_1, location_2]
}
end
let(:location_1) { instance_double("Thread::Backtrace::Location", to_s: "location 1") }
let(:location_2) { instance_double("Thread::Backtrace::Location", to_s: "location 2") }

def instrument_deprecation_warning
ActiveSupport::Notifications.instrument("deprecation.rails", payload)
end

it "emits a warning to the application logs" do
instrument_deprecation_warning

expect(rails_logger).to have_received(:warn).with(payload[:message])
end

it "emits a warning to Sentry" do
instrument_deprecation_warning

expect(Raven).to have_received(:capture_message).with(
payload[:message],
level: "warning",
extra: {
message: payload[:message],
gem_name: "Rails",
deprecation_horizon: "6.0",
callstack: ["location 1", "location 2"],
environment: Rails.env
}
)
end

it "emits a warning to Slack channel" do
slack_alert_title = "Deprecation Warning - #{app_name} (#{deploy_env})"

instrument_deprecation_warning

expect(slack_service).to have_received(:send_notification).with(
payload[:message],
slack_alert_title,
"#appeals-deprecation-alerts"
)
end

context "when an exception occurs" do
before { allow(slack_service).to receive(:send_notification).and_raise(StandardError) }

it "logs error to Sentry" do
instrument_deprecation_warning

expect(Raven).to have_received(:capture_exception).with(StandardError)
end

it "does not raise error" do
expect { instrument_deprecation_warning }.not_to raise_error
end
end
end
end

0 comments on commit 0e4fdbf

Please sign in to comment.