ddtrace 0.26.1 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +153 -77
  3. data/.circleci/images/primary/{Dockerfile-1.9.3 → Dockerfile-2.5.6} +8 -8
  4. data/.circleci/images/primary/Dockerfile-2.6.4 +73 -0
  5. data/.github/CODEOWNERS +1 -0
  6. data/Appraisals +201 -94
  7. data/CHANGELOG.md +25 -8
  8. data/Rakefile +153 -47
  9. data/ddtrace.gemspec +1 -1
  10. data/docker-compose.yml +56 -26
  11. data/docs/GettingStarted.md +117 -14
  12. data/lib/ddtrace.rb +4 -0
  13. data/lib/ddtrace/analytics.rb +9 -39
  14. data/lib/ddtrace/configuration.rb +0 -19
  15. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +144 -0
  16. data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +37 -0
  17. data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +25 -0
  18. data/lib/ddtrace/contrib/action_pack/ext.rb +16 -0
  19. data/lib/ddtrace/contrib/action_pack/integration.rb +36 -0
  20. data/lib/ddtrace/contrib/action_pack/patcher.rb +29 -0
  21. data/lib/ddtrace/contrib/action_pack/utils.rb +36 -0
  22. data/lib/ddtrace/contrib/action_view/configuration/settings.rb +24 -0
  23. data/lib/ddtrace/contrib/action_view/ext.rb +17 -0
  24. data/lib/ddtrace/contrib/action_view/instrumentation.rb +192 -0
  25. data/lib/ddtrace/contrib/action_view/integration.rb +43 -0
  26. data/lib/ddtrace/contrib/action_view/patcher.rb +47 -0
  27. data/lib/ddtrace/contrib/action_view/utils.rb +32 -0
  28. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +157 -0
  29. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +62 -0
  30. data/lib/ddtrace/contrib/active_support/cache/redis.rb +47 -0
  31. data/lib/ddtrace/contrib/active_support/configuration/settings.rb +23 -0
  32. data/lib/ddtrace/contrib/active_support/ext.rb +21 -0
  33. data/lib/ddtrace/contrib/active_support/integration.rb +38 -0
  34. data/lib/ddtrace/contrib/active_support/patcher.rb +29 -0
  35. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +24 -0
  36. data/lib/ddtrace/contrib/ethon/easy_patch.rb +139 -0
  37. data/lib/ddtrace/contrib/ethon/ext.rb +15 -0
  38. data/lib/ddtrace/contrib/ethon/integration.rb +35 -0
  39. data/lib/ddtrace/contrib/ethon/multi_patch.rb +80 -0
  40. data/lib/ddtrace/contrib/ethon/patcher.rb +27 -0
  41. data/lib/ddtrace/contrib/patchable.rb +1 -1
  42. data/lib/ddtrace/contrib/rails/configuration/settings.rb +43 -6
  43. data/lib/ddtrace/contrib/rails/ext.rb +0 -15
  44. data/lib/ddtrace/contrib/rails/framework.rb +37 -6
  45. data/lib/ddtrace/contrib/rails/middlewares.rb +2 -1
  46. data/lib/ddtrace/contrib/rails/patcher.rb +0 -8
  47. data/lib/ddtrace/contrib/rails/utils.rb +0 -46
  48. data/lib/ddtrace/contrib/redis/patcher.rb +12 -19
  49. data/lib/ddtrace/correlation.rb +8 -12
  50. data/lib/ddtrace/forced_tracing.rb +10 -38
  51. data/lib/ddtrace/sampler.rb +20 -74
  52. data/lib/ddtrace/span.rb +3 -4
  53. data/lib/ddtrace/tracer.rb +4 -11
  54. data/lib/ddtrace/version.rb +2 -2
  55. metadata +32 -9
  56. data/lib/ddtrace/contrib/rails/action_controller.rb +0 -100
  57. data/lib/ddtrace/contrib/rails/action_controller_patch.rb +0 -78
  58. data/lib/ddtrace/contrib/rails/action_view.rb +0 -19
  59. data/lib/ddtrace/contrib/rails/active_support.rb +0 -67
  60. data/lib/ddtrace/contrib/rails/core_extensions.rb +0 -353
@@ -0,0 +1,47 @@
1
+ require 'ddtrace/ext/http'
2
+ require 'ddtrace/contrib/patcher'
3
+ require 'ddtrace/contrib/action_view/ext'
4
+ require 'ddtrace/contrib/action_view/instrumentation'
5
+ require 'ddtrace/contrib/action_view/utils'
6
+
7
+ module Datadog
8
+ module Contrib
9
+ module ActionView
10
+ # Patcher enables patching of ActionView module.
11
+ module Patcher
12
+ include Contrib::Patcher
13
+
14
+ module_function
15
+
16
+ def patched?
17
+ done?(:action_view)
18
+ end
19
+
20
+ def patch
21
+ do_once(:action_view) do
22
+ begin
23
+ patch_renderer
24
+ rescue StandardError => e
25
+ Datadog::Tracer.log.error("Unable to apply Action View integration: #{e} Location: #{e.backtrace.first}")
26
+ end
27
+ end
28
+ end
29
+
30
+ def patch_renderer
31
+ do_once(:patch_renderer) do
32
+ if defined?(::ActionView::TemplateRenderer) && defined?(::ActionView::PartialRenderer)
33
+ ::ActionView::TemplateRenderer.send(:prepend, Instrumentation::TemplateRenderer::Rails31Plus)
34
+ ::ActionView::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer)
35
+ elsif defined?(::ActionView::Rendering) && defined?(::ActionView::Partials::PartialRenderer)
36
+ # NOTE: Rails < 3.1 compatibility: different classes are used
37
+ ::ActionView::Rendering.send(:prepend, Instrumentation::TemplateRenderer::Rails30)
38
+ ::ActionView::Partials::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer)
39
+ else
40
+ Datadog::Tracer.log.debug('Expected Template/Partial classes not found; template rendering disabled')
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,32 @@
1
+ require 'ddtrace/contrib/analytics'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActionView
6
+ # common utilities for Rails
7
+ module Utils
8
+ module_function
9
+
10
+ # in Rails the template name includes the template full path
11
+ # and it's better to avoid storing such information. This method
12
+ # returns the relative path from `views/` or the template name
13
+ # if a `views/` folder is not in the template full path. A wrong
14
+ # usage ensures that this method will not crash the tracing system.
15
+ def normalize_template_name(name)
16
+ return if name.nil?
17
+
18
+ base_path = Datadog.configuration[:action_view][:template_base_path]
19
+ sections_view = name.split(base_path)
20
+
21
+ if sections_view.length == 1
22
+ name.split('/')[-1]
23
+ else
24
+ sections_view[-1]
25
+ end
26
+ rescue
27
+ return name.to_s
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,157 @@
1
+ require 'ddtrace/contrib/active_support/ext'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActiveSupport
6
+ module Cache
7
+ # Defines instrumentation for ActiveSupport caching
8
+ # rubocop:disable Lint/RescueException
9
+ module Instrumentation
10
+ module_function
11
+
12
+ def start_trace_cache(payload)
13
+ tracer = Datadog.configuration[:active_support][:tracer]
14
+
15
+ # In most of the cases Rails ``fetch()`` and ``read()`` calls are nested.
16
+ # This check ensures that two reads are not nested since they don't provide
17
+ # interesting details.
18
+ # NOTE: the ``finish_trace_cache()`` is fired but it already has a safe-guard
19
+ # to avoid any kind of issue.
20
+ current_span = tracer.active_span
21
+ return if payload[:action] == Ext::RESOURCE_CACHE_GET &&
22
+ current_span.try(:name) == Ext::SPAN_CACHE &&
23
+ current_span.try(:resource) == Ext::RESOURCE_CACHE_GET
24
+
25
+ tracing_context = payload.fetch(:tracing_context)
26
+
27
+ # create a new ``Span`` and add it to the tracing context
28
+ service = Datadog.configuration[:active_support][:cache_service]
29
+ type = Ext::SPAN_TYPE_CACHE
30
+ span = tracer.trace(Ext::SPAN_CACHE, service: service, span_type: type)
31
+ span.resource = payload.fetch(:action)
32
+ tracing_context[:dd_cache_span] = span
33
+ rescue StandardError => e
34
+ Datadog::Tracer.log.debug(e.message)
35
+ end
36
+
37
+ def finish_trace_cache(payload)
38
+ # retrieve the tracing context and continue the trace
39
+ tracing_context = payload.fetch(:tracing_context)
40
+ span = tracing_context[:dd_cache_span]
41
+ return unless span && !span.finished?
42
+
43
+ begin
44
+ # discard parameters from the cache_store configuration
45
+ if defined?(::Rails)
46
+ store, = *Array.wrap(::Rails.configuration.cache_store).flatten
47
+ span.set_tag(Ext::TAG_CACHE_BACKEND, store)
48
+ end
49
+
50
+ normalized_key = ::ActiveSupport::Cache.expand_cache_key(payload.fetch(:key))
51
+ cache_key = Datadog::Utils.truncate(normalized_key, Ext::QUANTIZE_CACHE_MAX_KEY_SIZE)
52
+ span.set_tag(Ext::TAG_CACHE_KEY, cache_key)
53
+
54
+ span.set_error(payload[:exception]) if payload[:exception]
55
+ ensure
56
+ span.finish
57
+ end
58
+ rescue StandardError => e
59
+ Datadog::Tracer.log.debug(e.message)
60
+ end
61
+
62
+ # Defines instrumentation for ActiveSupport cache reading
63
+ module Read
64
+ def read(*args, &block)
65
+ payload = {
66
+ action: Ext::RESOURCE_CACHE_GET,
67
+ key: args[0],
68
+ tracing_context: {}
69
+ }
70
+
71
+ begin
72
+ # process and catch cache exceptions
73
+ Instrumentation.start_trace_cache(payload)
74
+ super
75
+ rescue Exception => e
76
+ payload[:exception] = [e.class.name, e.message]
77
+ payload[:exception_object] = e
78
+ raise e
79
+ end
80
+ ensure
81
+ Instrumentation.finish_trace_cache(payload)
82
+ end
83
+ end
84
+
85
+ # Defines instrumentation for ActiveSupport cache fetching
86
+ module Fetch
87
+ def fetch(*args, &block)
88
+ payload = {
89
+ action: Ext::RESOURCE_CACHE_GET,
90
+ key: args[0],
91
+ tracing_context: {}
92
+ }
93
+
94
+ begin
95
+ # process and catch cache exceptions
96
+ Instrumentation.start_trace_cache(payload)
97
+ super
98
+ rescue Exception => e
99
+ payload[:exception] = [e.class.name, e.message]
100
+ payload[:exception_object] = e
101
+ raise e
102
+ end
103
+ ensure
104
+ Instrumentation.finish_trace_cache(payload)
105
+ end
106
+ end
107
+
108
+ # Defines instrumentation for ActiveSupport cache writing
109
+ module Write
110
+ def write(*args, &block)
111
+ payload = {
112
+ action: Ext::RESOURCE_CACHE_SET,
113
+ key: args[0],
114
+ tracing_context: {}
115
+ }
116
+
117
+ begin
118
+ # process and catch cache exceptions
119
+ Instrumentation.start_trace_cache(payload)
120
+ super
121
+ rescue Exception => e
122
+ payload[:exception] = [e.class.name, e.message]
123
+ payload[:exception_object] = e
124
+ raise e
125
+ end
126
+ ensure
127
+ Instrumentation.finish_trace_cache(payload)
128
+ end
129
+ end
130
+
131
+ # Defines instrumentation for ActiveSupport cache deleting
132
+ module Delete
133
+ def delete(*args, &block)
134
+ payload = {
135
+ action: Ext::RESOURCE_CACHE_DELETE,
136
+ key: args[0],
137
+ tracing_context: {}
138
+ }
139
+
140
+ begin
141
+ # process and catch cache exceptions
142
+ Instrumentation.start_trace_cache(payload)
143
+ super
144
+ rescue Exception => e
145
+ payload[:exception] = [e.class.name, e.message]
146
+ payload[:exception_object] = e
147
+ raise e
148
+ end
149
+ ensure
150
+ Instrumentation.finish_trace_cache(payload)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,62 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/active_support/cache/instrumentation'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActiveSupport
7
+ module Cache
8
+ # Patcher enables patching of 'active_support' module.
9
+ module Patcher
10
+ include Contrib::Patcher
11
+
12
+ module_function
13
+
14
+ def patched?
15
+ done?(:cache)
16
+ end
17
+
18
+ def patch
19
+ do_once(:cache) do
20
+ begin
21
+ patch_cache_store_read
22
+ patch_cache_store_fetch
23
+ patch_cache_store_write
24
+ patch_cache_store_delete
25
+ rescue StandardError => e
26
+ Datadog::Tracer.log.error("Unable to apply Active Support cache integration: #{e}")
27
+ end
28
+ end
29
+ end
30
+
31
+ def cache_store_class(meth)
32
+ ::ActiveSupport::Cache::Store
33
+ end
34
+
35
+ def patch_cache_store_read
36
+ do_once(:patch_cache_store_read) do
37
+ cache_store_class(:read).send(:prepend, Cache::Instrumentation::Read)
38
+ end
39
+ end
40
+
41
+ def patch_cache_store_fetch
42
+ do_once(:patch_cache_store_fetch) do
43
+ cache_store_class(:fetch).send(:prepend, Cache::Instrumentation::Fetch)
44
+ end
45
+ end
46
+
47
+ def patch_cache_store_write
48
+ do_once(:patch_cache_store_write) do
49
+ cache_store_class(:write).send(:prepend, Cache::Instrumentation::Write)
50
+ end
51
+ end
52
+
53
+ def patch_cache_store_delete
54
+ do_once(:patch_cache_store_delete) do
55
+ cache_store_class(:delete).send(:prepend, Cache::Instrumentation::Delete)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,47 @@
1
+ require 'ddtrace/contrib/active_support/cache/patcher'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActiveSupport
6
+ module Cache
7
+ # Support for Redis with ActiveSupport
8
+ module Redis
9
+ # Patching behavior for Redis with ActiveSupport
10
+ module Patcher
11
+ # For Rails < 5.2 w/ redis-activesupport...
12
+ # When Redis is used, we can't only patch Cache::Store as it is
13
+ # Cache::RedisStore, a sub-class of it that is used, in practice.
14
+ # We need to do a per-method monkey patching as some of them might
15
+ # be redefined, and some of them not. The latest version of redis-activesupport
16
+ # redefines write but leaves untouched read and delete:
17
+ # https://github.com/redis-store/redis-activesupport/blob/master/lib/active_support/cache/redis_store.rb
18
+ #
19
+ # For Rails >= 5.2 w/o redis-activesupport...
20
+ # ActiveSupport includes a Redis cache store internally, and does not require these overrides.
21
+ # https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/redis_cache_store.rb
22
+ def patch_redis?(meth)
23
+ !Gem.loaded_specs['redis-activesupport'].nil? \
24
+ && defined?(::ActiveSupport::Cache::RedisStore) \
25
+ && ::ActiveSupport::Cache::RedisStore.instance_methods(false).include?(meth)
26
+ end
27
+
28
+ def cache_store_class(meth)
29
+ if patch_redis?(meth)
30
+ ::ActiveSupport::Cache::RedisStore
31
+ else
32
+ super
33
+ end
34
+ end
35
+ end
36
+
37
+ # Decorate Cache patcher with Redis support
38
+ Cache::Patcher.instance_eval do
39
+ class << self
40
+ prepend Redis::Patcher
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,23 @@
1
+ require 'ddtrace/contrib/configuration/settings'
2
+ require 'ddtrace/contrib/active_support/ext'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActiveSupport
7
+ module Configuration
8
+ # Custom settings for the ActiveSupport integration
9
+ class Settings < Contrib::Configuration::Settings
10
+ option :analytics_enabled,
11
+ default: -> { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, false) },
12
+ lazy: true
13
+
14
+ option :analytics_sample_rate,
15
+ default: -> { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) },
16
+ lazy: true
17
+
18
+ option :cache_service, default: Ext::SERVICE_CACHE
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,21 @@
1
+ module Datadog
2
+ module Contrib
3
+ module ActiveSupport
4
+ # ActiveSupport integration constants
5
+ module Ext
6
+ APP = 'active_support'.freeze
7
+ ENV_ANALYTICS_ENABLED = 'DD_ACTIVE_SUPPORT_ANALYTICS_ENABLED'.freeze
8
+ ENV_ANALYTICS_SAMPLE_RATE = 'DD_ACTIVE_SUPPORT_ANALYTICS_SAMPLE_RATE'.freeze
9
+ QUANTIZE_CACHE_MAX_KEY_SIZE = 300
10
+ RESOURCE_CACHE_DELETE = 'DELETE'.freeze
11
+ RESOURCE_CACHE_GET = 'GET'.freeze
12
+ RESOURCE_CACHE_SET = 'SET'.freeze
13
+ SERVICE_CACHE = 'active_support-cache'.freeze
14
+ SPAN_CACHE = 'rails.cache'.freeze
15
+ SPAN_TYPE_CACHE = 'cache'.freeze
16
+ TAG_CACHE_BACKEND = 'rails.cache.backend'.freeze
17
+ TAG_CACHE_KEY = 'rails.cache.key'.freeze
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,38 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/active_support/configuration/settings'
3
+ require 'ddtrace/contrib/active_support/patcher'
4
+
5
+ require 'ddtrace/contrib/active_support/cache/redis'
6
+
7
+ module Datadog
8
+ module Contrib
9
+ module ActiveSupport
10
+ # Describes the ActiveSupport integration
11
+ class Integration
12
+ include Contrib::Integration
13
+
14
+ register_as :active_support, auto_patch: false
15
+
16
+ def self.version
17
+ Gem.loaded_specs['activesupport'] && Gem.loaded_specs['activesupport'].version
18
+ end
19
+
20
+ def self.present?
21
+ super && defined?(::ActiveSupport)
22
+ end
23
+
24
+ def self.compatible?
25
+ super && version >= Gem::Version.new('3.0')
26
+ end
27
+
28
+ def default_configuration
29
+ Configuration::Settings.new
30
+ end
31
+
32
+ def patcher
33
+ ActiveSupport::Patcher
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,29 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/active_support/cache/patcher'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActiveSupport
7
+ # Patcher enables patching of 'active_support' module.
8
+ module Patcher
9
+ include Contrib::Patcher
10
+
11
+ module_function
12
+
13
+ def patched?
14
+ done?(:active_support)
15
+ end
16
+
17
+ def patch
18
+ do_once(:active_support) do
19
+ begin
20
+ Cache::Patcher.patch
21
+ rescue StandardError => e
22
+ Datadog::Tracer.log.error("Unable to apply Active Support integration: #{e}")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end