diff --git a/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb b/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb index 0b8820c8fec..40953753035 100644 --- a/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +++ b/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb @@ -81,7 +81,9 @@ def on_start(span, event, _id, payload) span.set_tag('EVENT', event) - set_cache_key(span, key, mapping[:multi_key]) + if Datadog.configuration.tracing[:active_support][:cache_key].enabled + set_cache_key(span, key, mapping[:multi_key]) + end rescue StandardError => e Datadog.logger.error(e.message) Datadog::Core::Telemetry::Logger.report(e) diff --git a/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb b/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb index 13c92a08418..81f14aef0ef 100644 --- a/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +++ b/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb @@ -3,6 +3,7 @@ require_relative '../../../../core/utils' require_relative '../../../metadata/ext' require_relative '../ext' +require_relative 'event' module Datadog module Tracing @@ -58,7 +59,8 @@ def trace(action, store, key: nil, multi_key: nil) end span.set_tag(Ext::TAG_CACHE_BACKEND, store) if store - set_cache_key(span, key, multi_key) + + set_cache_key(span, key, multi_key) if Datadog.configuration.tracing[:active_support][:cache_key].enabled yield end diff --git a/lib/datadog/tracing/contrib/active_support/configuration/settings.rb b/lib/datadog/tracing/contrib/active_support/configuration/settings.rb index 9f1b016ba7f..d7323c5afbb 100644 --- a/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +++ b/lib/datadog/tracing/contrib/active_support/configuration/settings.rb @@ -39,6 +39,16 @@ class Settings < Contrib::Configuration::Settings ) end end + + # grouped "cache_key.*" settings + settings :cache_key do + # enable or disabling the inclusion of the cache_key in the span + option :enabled do |o| + # cache_key.enabled + o.type :bool + o.default true + end + end end end end diff --git a/spec/datadog/tracing/contrib/rails/cache_spec.rb b/spec/datadog/tracing/contrib/rails/cache_spec.rb index 0a7ba0dda2f..4b3f79c2944 100644 --- a/spec/datadog/tracing/contrib/rails/cache_spec.rb +++ b/spec/datadog/tracing/contrib/rails/cache_spec.rb @@ -117,6 +117,21 @@ expect(set.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) .to eq('cache') end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + it do + expect(read).to eq(50) + + expect(spans).to have(2).items + get, = spans + expect(get.name).to eq('rails.cache') + expect(get.get_tag('rails.cache.key')).to be_nil + end + end end describe '#read_multi' do @@ -149,6 +164,20 @@ .to eq('cache') end end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + it do + expect(read_multi).to eq(Hash[multi_keys.zip([51, 52, 53])]) + expect(spans).to have(1 + multi_keys.size).items + get = spans[0] + expect(get.name).to eq('rails.cache') + expect(get.get_tag('rails.cache.keys')).to be_nil + end + end end describe '#write' do @@ -191,6 +220,20 @@ expect(span.get_tag('rails.cache.key')).to eq('custom-key/x/y/User:3') end end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + let(:key) { ['custom-key', %w[x y], user] } + let(:user) { double('User', cache_key: 'User:3') } + + it 'does not expand key using ActiveSupport when cache_key.enabled false' do + write + expect(span.get_tag('rails.cache.key')).to be_nil + end + end end describe '#write_multi' do @@ -240,6 +283,27 @@ expect(span.get_tag('rails.cache.keys')).to eq('["custom-key/x/y/User:3"]') end end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + it do + write_multi + expect(span.name).to eq('rails.cache') + expect(span.type).to eq('cache') + expect(span.resource).to eq('MSET') + expect(span.service).to eq('rails-cache') + expect(span.get_tag('rails.cache.backend')).to eq('file_store') + expect(span.get_tag('rails.cache.keys')).to be_nil + + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT)) + .to eq('active_support') + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) + .to eq('cache') + end + end end context 'when the method is not defined' do @@ -278,6 +342,27 @@ expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) .to eq('cache') end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + it do + delete + expect(span.name).to eq('rails.cache') + expect(span.type).to eq('cache') + expect(span.resource).to eq('DELETE') + expect(span.service).to eq('rails-cache') + expect(span.get_tag('rails.cache.backend')).to eq('file_store') + expect(span.get_tag('rails.cache.key')).to be_nil + + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT)) + .to eq('active_support') + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) + .to eq('cache') + end + end end describe '#fetch' do @@ -306,6 +391,32 @@ .to eq('cache') end end + + context 'when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + + subject(:fetch) { cache.fetch('exception') { raise 'oops' } } + + it do + expect { fetch }.to raise_error(StandardError) + + expect(span.name).to eq('rails.cache') + expect(span.type).to eq('cache') + expect(span.resource).to eq('GET') + expect(span.service).to eq('rails-cache') + expect(span.get_tag('rails.cache.backend')).to eq('file_store') + expect(span.get_tag('rails.cache.key')).to be_nil + expect(span.get_tag('error.type')).to eq('RuntimeError') + expect(span.get_tag('error.message')).to eq('oops') + + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT)) + .to eq('active_support') + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) + .to eq('cache') + end + end end describe '#fetch_multi' do @@ -340,6 +451,30 @@ .to eq('cache') end end + + context 'with exception and when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + subject(:fetch_multi) { cache.fetch_multi('exception', 'another', 'one') { raise 'oops' } } + + it do + expect { fetch_multi }.to raise_error(StandardError) + expect(span.name).to eq('rails.cache') + expect(span.type).to eq('cache') + expect(span.resource).to eq('MGET') + expect(span.service).to eq('rails-cache') + expect(span.get_tag('rails.cache.backend')).to eq('file_store') + expect(span.get_tag('rails.cache.keys')).to be_nil + expect(span.get_tag('error.type')).to eq('RuntimeError') + expect(span.get_tag('error.message')).to eq('oops') + + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT)) + .to eq('active_support') + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) + .to eq('cache') + end + end end context 'when the method is not defined' do @@ -378,4 +513,24 @@ .to eq('cache') end end + + context 'with very large cache key and when cache_key.enabled is false' do + before do + Datadog.configuration.tracing[:active_support][:cache_key].enabled = false + end + it 'truncates key too large' do + max_key_size = Datadog::Tracing::Contrib::ActiveSupport::Ext::QUANTIZE_CACHE_MAX_KEY_SIZE + large_key = ''.ljust(max_key_size * 2, SecureRandom.hex) + cache.write(large_key, 'foobar') + + expect(large_key.size).to be > max_key_size + expect(span.name).to eq('rails.cache') + expect(span.get_tag('rails.cache.key')).to be_nil + + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_COMPONENT)) + .to eq('active_support') + expect(span.get_tag(Datadog::Tracing::Metadata::Ext::TAG_OPERATION)) + .to eq('cache') + end + end end