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

Bump express from 4.18.2 to 4.21.0 in /sentry-rails/examples/rails-6.0 #2

Closed
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

- Add support for $SENTRY_DEBUG and $SENTRY_SPOTLIGHT ([#2374](https://github.com/getsentry/sentry-ruby/pull/2374))
- Support human readable intervals in `sidekiq-cron` ([#2387](https://github.com/getsentry/sentry-ruby/pull/2387))
- Add support for Sentry Cache instrumentation, when using Rails.cache ([#2380](https://github.com/getsentry/sentry-ruby/pull/2380))

## 5.19.0

Expand Down
238 changes: 159 additions & 79 deletions sentry-rails/examples/rails-6.0/yarn.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions sentry-rails/lib/sentry/rails/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
require "sentry/rails/tracing/action_view_subscriber"
require "sentry/rails/tracing/active_record_subscriber"
require "sentry/rails/tracing/active_storage_subscriber"
require "sentry/rails/tracing/active_support_subscriber"

module Sentry
class Configuration
Expand Down Expand Up @@ -162,6 +163,7 @@ def initialize
end
@tracing_subscribers = Set.new([
Sentry::Rails::Tracing::ActionViewSubscriber,
Sentry::Rails::Tracing::ActiveSupportSubscriber,
Sentry::Rails::Tracing::ActiveRecordSubscriber,
Sentry::Rails::Tracing::ActiveStorageSubscriber
])
Expand Down
63 changes: 63 additions & 0 deletions sentry-rails/lib/sentry/rails/tracing/active_support_subscriber.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
require "sentry/rails/tracing/abstract_subscriber"

module Sentry
module Rails
module Tracing
class ActiveSupportSubscriber < AbstractSubscriber
READ_EVENT_NAMES = %w[
cache_read.active_support
].freeze

WRITE_EVENT_NAMES = %w[
cache_write.active_support
cache_increment.active_support
cache_decrement.active_support
].freeze

REMOVE_EVENT_NAMES = %w[
cache_delete.active_support
].freeze

FLUSH_EVENT_NAMES = %w[
cache_prune.active_support
].freeze

EVENT_NAMES = READ_EVENT_NAMES + WRITE_EVENT_NAMES + REMOVE_EVENT_NAMES + FLUSH_EVENT_NAMES

SPAN_ORIGIN = "auto.cache.rails".freeze

def self.subscribe!
subscribe_to_event(EVENT_NAMES) do |event_name, duration, payload|
record_on_current_span(
op: operation_name(event_name),
origin: SPAN_ORIGIN,
start_timestamp: payload[START_TIMESTAMP_NAME],
description: payload[:store],
duration: duration
) do |span|
span.set_data("cache.key", [*payload[:key]].select { |key| Utils::EncodingHelper.valid_utf_8?(key) })
span.set_data("cache.hit", payload[:hit] == true) # Handle nil case
end
end
end

private

def self.operation_name(event_name)
case
when READ_EVENT_NAMES.include?(event_name)
"cache.get"
when WRITE_EVENT_NAMES.include?(event_name)
"cache.put"
when REMOVE_EVENT_NAMES.include?(event_name)
"cache.remove"
when FLUSH_EVENT_NAMES.include?(event_name)
"cache.flush"
else
"other"
end
end
end
end
end
end
2 changes: 2 additions & 0 deletions sentry-rails/spec/dummy/test_rails_app/app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ def self.name
app.config.logger = ActiveSupport::Logger.new(nil)
app.config.eager_load = true
app.config.active_job.queue_adapter = :test
app.config.cache_store = :memory_store
app.config.action_controller.perform_caching = true

# Eager load namespaces can be accumulated after repeated initializations and make initialization
# slower after each run
Expand Down
4 changes: 2 additions & 2 deletions sentry-rails/spec/sentry/rails/configuration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
class MySubscriber; end

it "returns the default subscribers" do
expect(subject.tracing_subscribers.size).to eq(3)
expect(subject.tracing_subscribers.size).to eq(4)
end

it "is customizable" do
subject.tracing_subscribers << MySubscriber
expect(subject.tracing_subscribers.size).to eq(4)
expect(subject.tracing_subscribers.size).to eq(5)
end

it "is replaceable" do
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
require "spec_helper"

RSpec.describe Sentry::Rails::Tracing::ActiveSupportSubscriber, :subscriber, type: :request do
let(:transport) do
Sentry.get_current_client.transport
end

context "when transaction is sampled" do
before do
make_basic_app do |config, app|
config.traces_sample_rate = 1.0
config.rails.tracing_subscribers = [described_class]
end
end

it "tracks cache write" do
transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)

Rails.cache.write("my_cache_key", "my_cache_value")
transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")

expect(cache_transaction[:spans].count).to eq(1)
expect(cache_transaction[:spans][0][:op]).to eq("cache.put")
expect(cache_transaction[:spans][0][:origin]).to eq("auto.cache.rails")
end

#
it "tracks cache increment" do
skip("Tracks on Rails 8.0 for all Cache Stores; Until then only MemCached and Redis Stores.") if Rails.version.to_f < 8.0

Rails.cache.write("my_cache_key", 0)

transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)
Rails.cache.increment("my_cache_key")

transaction.finish

expect(Rails.cache.read("my_cache_key")).to eq(1)
expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(2)
expect(cache_transaction[:spans][1][:op]).to eq("cache.put")
expect(cache_transaction[:spans][1][:origin]).to eq("auto.cache.rails")
end

#
it "tracks cache decrement" do
skip("Tracks on Rails 8.0 for all Cache Stores; Until then only MemCached and Redis Stores.") if Rails.version.to_f < 8.0

Rails.cache.write("my_cache_key", 0)

transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)
Rails.cache.decrement("my_cache_key")

transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(2)
expect(cache_transaction[:spans][1][:op]).to eq("cache.put")
expect(cache_transaction[:spans][1][:origin]).to eq("auto.cache.rails")
end

it "tracks cache read" do
transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)
Rails.cache.read("my_cache_key")

transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(1)
expect(cache_transaction[:spans][0][:op]).to eq("cache.get")
expect(cache_transaction[:spans][0][:origin]).to eq("auto.cache.rails")
end

it "tracks cache delete" do
transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)

Rails.cache.read("my_cache_key")

transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(1)
expect(cache_transaction[:spans][0][:op]).to eq("cache.get")
expect(cache_transaction[:spans][0][:origin]).to eq("auto.cache.rails")
end
it "tracks cache prune" do
transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)

Rails.cache.write("my_cache_key", 123, expires_in: 0.seconds)

Rails.cache.prune(0)

transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(2)
expect(cache_transaction[:spans][1][:op]).to eq("cache.flush")
expect(cache_transaction[:spans][1][:origin]).to eq("auto.cache.rails")
end

it "tracks sets cache hit" do
Rails.cache.write("my_cache_key", "my_cache_value")
transaction = Sentry::Transaction.new(sampled: true, hub: Sentry.get_current_hub)
Sentry.get_current_scope.set_span(transaction)
Rails.cache.read("my_cache_key")
Rails.cache.read("my_cache_key_non_existing")

transaction.finish

expect(transport.events.count).to eq(1)
cache_transaction = transport.events.first.to_hash
expect(cache_transaction[:type]).to eq("transaction")
expect(cache_transaction[:spans].count).to eq(2)
expect(cache_transaction[:spans][0][:op]).to eq("cache.get")
expect(cache_transaction[:spans][0][:origin]).to eq("auto.cache.rails")
expect(cache_transaction[:spans][0][:data]['cache.hit']).to eq(true)

expect(cache_transaction[:spans][1][:op]).to eq("cache.get")
expect(cache_transaction[:spans][1][:origin]).to eq("auto.cache.rails")
expect(cache_transaction[:spans][1][:data]['cache.hit']).to eq(false)
end
end

context "when transaction is not sampled" do
before do
make_basic_app
end

it "doesn't record spans" do
Rails.cache.write("my_cache_key", "my_cache_value")

expect(transport.events.count).to eq(0)
end
end
end
Loading