diff --git a/lib/rails_semantic_logger/active_record/log_subscriber.rb b/lib/rails_semantic_logger/active_record/log_subscriber.rb index 357303b..5fe56e5 100644 --- a/lib/rails_semantic_logger/active_record/log_subscriber.rb +++ b/lib/rails_semantic_logger/active_record/log_subscriber.rb @@ -54,11 +54,25 @@ def sql(event) # When multiple values are received for a single bound field, it is converted into an array def add_bind_value(binds, key, value) - key = key.downcase.to_sym unless key.nil? - value = (Array(binds[key]) << value) if binds.key?(key) + key = key.downcase.to_sym unless key.nil? + + if rails_filter_params_include?(key) + value = "[FILTERED]" + elsif binds.key?(key) + value = (Array(binds[key]) << value) + end + binds[key] = value end + def rails_filter_params_include?(key) + filter_parameters = Rails.configuration.filter_parameters + + return filter_parameters.first.match? key if filter_parameters.first.is_a? Regexp + + filter_parameters.include? key + end + def logger self.class.logger end diff --git a/test/active_record_test.rb b/test/active_record_test.rb index 0fc3866..e1b3a0f 100644 --- a/test/active_record_test.rb +++ b/test/active_record_test.rb @@ -87,6 +87,62 @@ class ActiveRecordTest < Minitest::Test assert_instance_of Integer, messages[0].payload[:allocations] if Rails.version.to_i >= 6 end + it "filtered bind value" do + filter_params_setting true, %i[name] do + expected_sql = + if Rails.version.to_f >= 5.2 + "SELECT #{extra_space}\"samples\".* FROM \"samples\" WHERE \"samples\".\"name\" = ? ORDER BY \"samples\".\"id\" ASC LIMIT ?" + else + "SELECT \"samples\".* FROM \"samples\" WHERE \"samples\".\"name\" = ? ORDER BY \"samples\".\"id\" ASC LIMIT ?" + end + + messages = semantic_logger_events do + Sample.where(name: "Jack").first + end + assert_equal 1, messages.count, messages + + assert_semantic_logger_event( + messages[0], + level: :debug, + name: "ActiveRecord", + message: "Sample Load", + payload_includes: { + sql: expected_sql, + binds: {name: "[FILTERED]", limit: 1} + } + ) + assert_instance_of Integer, messages[0].payload[:allocations] if Rails.version.to_i >= 6 + end + end + + it "filtered bind value when filter_parameters set as regex" do + filter_params_regex_setting true, %i[name] do + expected_sql = + if Rails.version.to_f >= 5.2 + "SELECT #{extra_space}\"samples\".* FROM \"samples\" WHERE \"samples\".\"name\" = ? ORDER BY \"samples\".\"id\" ASC LIMIT ?" + else + "SELECT \"samples\".* FROM \"samples\" WHERE \"samples\".\"name\" = ? ORDER BY \"samples\".\"id\" ASC LIMIT ?" + end + + messages = semantic_logger_events do + Sample.where(name: "Jack").first + end + assert_equal 1, messages.count, messages + + assert_semantic_logger_event( + messages[0], + level: :debug, + name: "ActiveRecord", + message: "Sample Load", + payload_includes: { + sql: expected_sql, + binds: {name: "[FILTERED]", limit: 1} + } + ) + assert_instance_of Integer, messages[0].payload[:allocations] if Rails.version.to_i >= 6 + end + end + it "multiple bind values" do skip "Not applicable to older rails" if Rails.version.to_f <= 5.1 diff --git a/test/dummy/db/test.sqlite3 b/test/dummy/db/test.sqlite3 index a720ed8..cebf7e6 100644 Binary files a/test/dummy/db/test.sqlite3 and b/test/dummy/db/test.sqlite3 differ diff --git a/test/test_helper.rb b/test/test_helper.rb index 7d85f90..39cb10c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -23,3 +23,27 @@ Minitest::Test.include SemanticLogger::Test::Minitest ActionMailer::Base.delivery_method = :test + +def filter_params_setting(value, user_defined_params, &block) + original_value = Rails.configuration.filter_parameters + Rails.configuration.filter_parameters = user_defined_params + block.call +ensure + Rails.configuration.filter_parameters = original_value +end + +def filter_params_regex_setting(value, user_defined_params, &block) + original_value = Rails.configuration.filter_parameters + + Rails.configuration.filter_parameters += user_defined_params + + filter_params_regex = Rails.configuration.filter_parameters.map do |key| + "(?i:#{key})" + end.join("|") + + Rails.configuration.filter_parameters = [/(?-mix:#{filter_params_regex})/] + + block.call +ensure + Rails.configuration.filter_parameters = original_value +end