Skip to content

Commit 299d82e

Browse files
committed
feat(data-collection): Port Rails controller and ActiveStorage
Rails controller span data is slightly modified to comply with URL collection spec.
1 parent 0b2ef30 commit 299d82e

6 files changed

Lines changed: 141 additions & 13 deletions

File tree

sentry-rails/lib/sentry/rails/controller_transaction.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
# frozen_string_literal: true
22

3+
require "sentry/utils/http_tracing"
4+
35
module Sentry
46
module Rails
57
module ControllerTransaction
68
SPAN_ORIGIN = "auto.view.rails"
79

10+
include Sentry::Utils::HttpTracing
11+
812
def self.included(base)
913
base.prepend_around_action(:sentry_around_action)
1014
end
@@ -24,9 +28,16 @@ def sentry_around_action
2428
child_span.set_data(:format, request.format)
2529
child_span.set_data(:method, request.method)
2630

27-
pii = Sentry.configuration.send_default_pii
28-
child_span.set_data(:path, pii ? request.fullpath : request.filtered_path)
29-
child_span.set_data(:params, pii ? request.params : request.filtered_parameters)
31+
data_collection = Sentry.configuration.data_collection
32+
query = data_collection.url_query_params.filter(request.query_parameters)
33+
path = request.path
34+
path = "#{path}?#{format_query(query)}" unless query.empty?
35+
36+
child_span.set_data(:path, path)
37+
child_span.set_data(
38+
:params,
39+
data_collection.url_query_params.filter(request.params)
40+
)
3041
end
3142

3243
result

sentry-rails/lib/sentry/rails/railtie.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Railtie < ::Rails::Railtie
4848
next unless Sentry.initialized?
4949

5050
configure_project_root
51+
configure_data_collection
5152
configure_trusted_proxies
5253
configure_cron_timezone
5354
extend_controller_methods if defined?(ActionController)
@@ -82,6 +83,14 @@ def configure_project_root
8283
Sentry.configuration.project_root = ::Rails.root.to_s
8384
end
8485

86+
def configure_data_collection
87+
collection = Sentry.configuration.data_collection.url_query_params
88+
return unless collection.mode == :deny_list
89+
90+
filter_parameters = ::Rails.application.config.filter_parameters
91+
collection.terms = Array(collection.terms) + Array(filter_parameters)
92+
end
93+
8594
def configure_trusted_proxies
8695
Sentry.configuration.trusted_proxies += Array(::Rails.application.config.action_dispatch.trusted_proxies)
8796
end

sentry-rails/lib/sentry/rails/tracing/active_storage_subscriber.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ def self.subscribe!
3434
) do |span|
3535
payload.each do |key, value|
3636
next if key == START_TIMESTAMP_NAME
37-
next if key == :key && !Sentry.configuration.send_default_pii
37+
# Active Storage keys are automatically generated storage data,
38+
# rather than URL/query data. Use the database query-data switch
39+
# for the legacy PII-compatible on/off behavior.
40+
next if key == :key && !Sentry.configuration.data_collection.database_query_data
3841

3942
span.set_data(key, value)
4043
end

sentry-rails/spec/sentry/rails/tracing/active_storage_subscriber_spec.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,54 @@
7979
end
8080
end
8181

82+
context "data collection" do
83+
context "with database query data enabled" do
84+
before do
85+
make_basic_app do |config|
86+
config.traces_sample_rate = 1.0
87+
config.rails.tracing_subscribers = [described_class]
88+
config.data_collection.database_query_data = true
89+
end
90+
end
91+
92+
it "records the :key in span.data" do
93+
ActiveStorage::AnalyzeJob.queue_adapter.perform_enqueued_jobs = true
94+
95+
p = Post.create!
96+
get "/posts/#{p.id}/attach"
97+
98+
request_transaction = transport.events.last.to_h
99+
upload_span = request_transaction[:spans].find { |s| s[:op] == "file.service_upload.active_storage" }
100+
101+
expect(upload_span).not_to be_nil
102+
expect(upload_span.dig(:data, :key)).to eq(p.cover.key)
103+
end
104+
end
105+
106+
context "with database query data disabled" do
107+
before do
108+
make_basic_app do |config|
109+
config.traces_sample_rate = 1.0
110+
config.rails.tracing_subscribers = [described_class]
111+
config.data_collection.database_query_data = false
112+
end
113+
end
114+
115+
it "does not record the :key in span.data" do
116+
ActiveStorage::AnalyzeJob.queue_adapter.perform_enqueued_jobs = true
117+
118+
p = Post.create!
119+
get "/posts/#{p.id}/attach"
120+
121+
request_transaction = transport.events.last.to_h
122+
upload_span = request_transaction[:spans].find { |s| s[:op] == "file.service_upload.active_storage" }
123+
124+
expect(upload_span).not_to be_nil
125+
expect(upload_span.dig(:data, :key)).to be_nil
126+
end
127+
end
128+
end
129+
82130
context "when transaction is not sampled" do
83131
before do
84132
make_basic_app

sentry-rails/spec/sentry/rails/tracing_spec.rb

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,15 @@
201201
end
202202
end
203203

204-
it "does not record sensitive params" do
204+
it "does not record any params" do
205205
get "/posts?foo=bar&password=42&secret=baz"
206206
transaction = transport.events.last.to_h
207207

208208
params = transaction[:spans][0][:data][:params]
209-
expect(params["foo"]).to eq("bar")
210-
expect(params["password"]).to eq("[FILTERED]")
211-
expect(params["secret"]).to eq("[FILTERED]")
209+
expect(params).to be_empty
212210

213211
path = transaction[:spans][0][:data][:path]
214-
expect(path).to eq("/posts?foo=bar&password=[FILTERED]&secret=[FILTERED]")
212+
expect(path).to eq("/posts")
215213
end
216214
end
217215

@@ -223,17 +221,61 @@
223221
end
224222
end
225223

226-
it "records all params" do
224+
it "records all params except sensitive params" do
227225
get "/posts?foo=bar&password=42&secret=baz"
228226
transaction = transport.events.last.to_h
229227

230228
params = transaction[:spans][0][:data][:params]
231229
expect(params["foo"]).to eq("bar")
232-
expect(params["password"]).to eq("42")
233-
expect(params["secret"]).to eq("baz")
230+
expect(params["password"]).to eq("[Filtered]")
231+
expect(params["secret"]).to eq("[Filtered]")
232+
233+
path = transaction[:spans][0][:data][:path]
234+
expect(path).to eq("/posts?foo=bar&password=[Filtered]&secret=[Filtered]")
235+
end
236+
end
237+
end
238+
239+
context "data collection" do
240+
context "with url query params enabled" do
241+
before do
242+
make_basic_app do |config|
243+
config.traces_sample_rate = 1.0
244+
config.data_collection.url_query_params.mode = :deny_list
245+
end
246+
end
247+
248+
it "records query params except sensitive params" do
249+
get "/posts?foo=bar&password=42&secret=baz"
250+
transaction = transport.events.last.to_h
251+
252+
params = transaction[:spans][0][:data][:params]
253+
expect(params["foo"]).to eq("bar")
254+
expect(params["password"]).to eq("[Filtered]")
255+
expect(params["secret"]).to eq("[Filtered]")
256+
257+
path = transaction[:spans][0][:data][:path]
258+
expect(path).to eq("/posts?foo=bar&password=[Filtered]&secret=[Filtered]")
259+
end
260+
end
261+
262+
context "with url query params disabled" do
263+
before do
264+
make_basic_app do |config|
265+
config.traces_sample_rate = 1.0
266+
config.data_collection.url_query_params.mode = :off
267+
end
268+
end
269+
270+
it "does not record query params" do
271+
get "/posts?foo=bar&password=42&secret=baz"
272+
transaction = transport.events.last.to_h
273+
274+
params = transaction[:spans][0][:data][:params]
275+
expect(params).to be_empty
234276

235277
path = transaction[:spans][0][:data][:path]
236-
expect(path).to eq("/posts?foo=bar&password=42&secret=baz")
278+
expect(path).to eq("/posts")
237279
end
238280
end
239281
end

sentry-rails/spec/sentry/rails_spec.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,21 @@
105105
end
106106
end
107107

108+
context "data collection" do
109+
before do
110+
make_basic_app do |config|
111+
config.data_collection.url_query_params.mode = :deny_list
112+
end
113+
end
114+
115+
it "adds Rails filter parameters to URL query parameter data collection" do
116+
expect(Sentry.configuration.data_collection.url_query_params.terms).to include(
117+
"password",
118+
"custom_secret"
119+
)
120+
end
121+
end
122+
108123
context "at exit" do
109124
before do
110125
make_basic_app

0 commit comments

Comments
 (0)