ddtrace 0.30.1 → 0.31.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 (85) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +28 -0
  3. data/.circleci/images/primary/Dockerfile-2.7.0 +73 -0
  4. data/Appraisals +111 -2
  5. data/CHANGELOG.md +33 -1
  6. data/Rakefile +69 -1
  7. data/ddtrace.gemspec +1 -0
  8. data/docker-compose.yml +30 -0
  9. data/docs/GettingStarted.md +28 -3
  10. data/lib/ddtrace.rb +6 -0
  11. data/lib/ddtrace/buffer.rb +3 -3
  12. data/lib/ddtrace/configuration/base.rb +2 -1
  13. data/lib/ddtrace/configuration/settings.rb +15 -2
  14. data/lib/ddtrace/context.rb +62 -57
  15. data/lib/ddtrace/context_flush.rb +51 -114
  16. data/lib/ddtrace/context_provider.rb +45 -0
  17. data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +25 -0
  18. data/lib/ddtrace/contrib/action_cable/event.rb +65 -0
  19. data/lib/ddtrace/contrib/action_cable/events.rb +33 -0
  20. data/lib/ddtrace/contrib/action_cable/events/broadcast.rb +49 -0
  21. data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +52 -0
  22. data/lib/ddtrace/contrib/action_cable/events/transmit.rb +50 -0
  23. data/lib/ddtrace/contrib/action_cable/ext.rb +23 -0
  24. data/lib/ddtrace/contrib/action_cable/instrumentation.rb +31 -0
  25. data/lib/ddtrace/contrib/action_cable/integration.rb +36 -0
  26. data/lib/ddtrace/contrib/action_cable/patcher.rb +27 -0
  27. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +2 -2
  28. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +5 -3
  29. data/lib/ddtrace/contrib/action_view/events/render_template.rb +5 -3
  30. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +2 -1
  31. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +4 -2
  32. data/lib/ddtrace/contrib/action_view/patcher.rb +1 -1
  33. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +1 -1
  34. data/lib/ddtrace/contrib/active_record/events/sql.rb +1 -1
  35. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +2 -2
  36. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
  37. data/lib/ddtrace/contrib/dalli/patcher.rb +1 -1
  38. data/lib/ddtrace/contrib/dalli/quantize.rb +1 -1
  39. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +1 -1
  40. data/lib/ddtrace/contrib/excon/middleware.rb +3 -3
  41. data/lib/ddtrace/contrib/faraday/connection.rb +18 -0
  42. data/lib/ddtrace/contrib/faraday/integration.rb +1 -1
  43. data/lib/ddtrace/contrib/faraday/patcher.rb +3 -3
  44. data/lib/ddtrace/contrib/grape/endpoint.rb +5 -5
  45. data/lib/ddtrace/contrib/grape/patcher.rb +1 -1
  46. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +1 -1
  47. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +2 -2
  48. data/lib/ddtrace/contrib/grpc/patcher.rb +1 -1
  49. data/lib/ddtrace/contrib/http/instrumentation.rb +1 -1
  50. data/lib/ddtrace/contrib/mongodb/subscribers.rb +2 -2
  51. data/lib/ddtrace/contrib/patchable.rb +1 -1
  52. data/lib/ddtrace/contrib/patcher.rb +1 -1
  53. data/lib/ddtrace/contrib/rack/middlewares.rb +2 -2
  54. data/lib/ddtrace/contrib/rack/patcher.rb +2 -2
  55. data/lib/ddtrace/contrib/rack/request_queue.rb +1 -1
  56. data/lib/ddtrace/contrib/rails/configuration/settings.rb +1 -0
  57. data/lib/ddtrace/contrib/rails/framework.rb +12 -0
  58. data/lib/ddtrace/contrib/rake/instrumentation.rb +2 -2
  59. data/lib/ddtrace/contrib/redis/quantize.rb +1 -1
  60. data/lib/ddtrace/contrib/sinatra/tracer.rb +1 -1
  61. data/lib/ddtrace/ext/forced_tracing.rb +1 -1
  62. data/lib/ddtrace/ext/sampling.rb +3 -0
  63. data/lib/ddtrace/logger.rb +42 -0
  64. data/lib/ddtrace/metrics.rb +5 -5
  65. data/lib/ddtrace/monkey.rb +1 -1
  66. data/lib/ddtrace/pin.rb +1 -1
  67. data/lib/ddtrace/pipeline.rb +1 -1
  68. data/lib/ddtrace/propagation/http_propagator.rb +2 -2
  69. data/lib/ddtrace/runtime/cgroup.rb +1 -1
  70. data/lib/ddtrace/runtime/container.rb +1 -1
  71. data/lib/ddtrace/runtime/metrics.rb +1 -1
  72. data/lib/ddtrace/sampler.rb +1 -1
  73. data/lib/ddtrace/sampling/rule.rb +1 -1
  74. data/lib/ddtrace/sampling/rule_sampler.rb +4 -4
  75. data/lib/ddtrace/span.rb +24 -6
  76. data/lib/ddtrace/sync_writer.rb +4 -3
  77. data/lib/ddtrace/tracer.rb +37 -77
  78. data/lib/ddtrace/transport/http/client.rb +2 -2
  79. data/lib/ddtrace/utils.rb +1 -1
  80. data/lib/ddtrace/version.rb +2 -2
  81. data/lib/ddtrace/workers.rb +3 -3
  82. data/lib/ddtrace/writer.rb +3 -2
  83. metadata +44 -6
  84. data/lib/ddtrace/contrib/faraday/rack_builder.rb +0 -18
  85. data/lib/ddtrace/provider.rb +0 -21
@@ -0,0 +1,45 @@
1
+ module Datadog
2
+ # DefaultContextProvider is a default context provider that retrieves
3
+ # all contexts from the current thread-local storage. It is suitable for
4
+ # synchronous programming.
5
+ class DefaultContextProvider
6
+ # Initializes the default context provider with a thread-bound context.
7
+ def initialize
8
+ @context = ThreadLocalContext.new
9
+ end
10
+
11
+ # Sets the current context.
12
+ def context=(ctx)
13
+ @context.local = ctx
14
+ end
15
+
16
+ # Return the current context.
17
+ def context
18
+ @context.local
19
+ end
20
+ end
21
+
22
+ # ThreadLocalContext can be used as a tracer global reference to create
23
+ # a different \Context for each thread. In synchronous tracer, this
24
+ # is required to prevent multiple threads sharing the same \Context
25
+ # in different executions.
26
+ class ThreadLocalContext
27
+ # ThreadLocalContext can be used as a tracer global reference to create
28
+ # a different \Context for each thread. In synchronous tracer, this
29
+ # is required to prevent multiple threads sharing the same \Context
30
+ # in different executions.
31
+ def initialize
32
+ self.local = Datadog::Context.new
33
+ end
34
+
35
+ # Override the thread-local context with a new context.
36
+ def local=(ctx)
37
+ Thread.current[:datadog_context] = ctx
38
+ end
39
+
40
+ # Return the thread-local context.
41
+ def local
42
+ Thread.current[:datadog_context] ||= Datadog::Context.new
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,25 @@
1
+ require 'ddtrace/contrib/configuration/settings'
2
+ require 'ddtrace/contrib/action_cable/ext'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActionCable
7
+ module Configuration
8
+ # Custom settings for the ActionCable integration
9
+ class Settings < Contrib::Configuration::Settings
10
+ option :analytics_enabled do |o|
11
+ o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, false) }
12
+ o.lazy
13
+ end
14
+
15
+ option :analytics_sample_rate do |o|
16
+ o.default { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) }
17
+ o.lazy
18
+ end
19
+
20
+ option :service_name, default: Ext::SERVICE_NAME
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,65 @@
1
+ require 'ddtrace/contrib/analytics'
2
+ require 'ddtrace/contrib/active_support/notifications/event'
3
+ require 'ddtrace/contrib/action_cable/ext'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module ActionCable
8
+ # Defines basic behaviors for an event.
9
+ module Event
10
+ def self.included(base)
11
+ base.send(:include, ActiveSupport::Notifications::Event)
12
+ base.send(:extend, ClassMethods)
13
+ end
14
+
15
+ # Class methods for events.
16
+ module ClassMethods
17
+ def span_options
18
+ { service: configuration[:service_name] }
19
+ end
20
+
21
+ def tracer
22
+ -> { configuration[:tracer] }
23
+ end
24
+
25
+ def configuration
26
+ Datadog.configuration[:action_cable]
27
+ end
28
+ end
29
+ end
30
+
31
+ # Defines behavior for the first event of a thread execution.
32
+ #
33
+ # This event is not expected to be nested with other event,
34
+ # but to start a fresh tracing context.
35
+ module RootContextEvent
36
+ def self.included(base)
37
+ base.send(:include, ActiveSupport::Notifications::Event)
38
+ base.send(:extend, ClassMethods)
39
+ end
40
+
41
+ # Class methods for events.
42
+ module ClassMethods
43
+ include Contrib::ActionCable::Event::ClassMethods
44
+
45
+ def subscription(*args)
46
+ super.tap do |subscription|
47
+ subscription.before_trace { ensure_clean_context! }
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ # Context objects are thread-bound.
54
+ # If an integration re-uses threads, context from a previous trace
55
+ # could leak into the new trace. This "cleans" current context,
56
+ # preventing such a leak.
57
+ def ensure_clean_context!
58
+ return unless configuration[:tracer].call_context.current_span
59
+ configuration[:tracer].provider.context = Context.new
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,33 @@
1
+ require 'ddtrace/contrib/action_cable/event'
2
+ require 'ddtrace/contrib/action_cable/events/broadcast'
3
+ require 'ddtrace/contrib/action_cable/events/perform_action'
4
+ require 'ddtrace/contrib/action_cable/events/transmit'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module ActionCable
9
+ # Defines collection of instrumented ActionCable events
10
+ module Events
11
+ ALL = [
12
+ Events::Broadcast,
13
+ Events::PerformAction,
14
+ Events::Transmit
15
+ ].freeze
16
+
17
+ module_function
18
+
19
+ def all
20
+ self::ALL
21
+ end
22
+
23
+ def subscriptions
24
+ all.collect(&:subscriptions).collect(&:to_a).flatten
25
+ end
26
+
27
+ def subscribe!
28
+ all.each(&:subscribe!)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,49 @@
1
+ require 'ddtrace/contrib/analytics'
2
+ require 'ddtrace/contrib/action_cable/event'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActionCable
7
+ module Events
8
+ # Defines instrumentation for 'broadcast.action_cable' event.
9
+ #
10
+ # A single 'broadcast' event will trigger as many 'transmit' events
11
+ # as there are clients subscribed to a channel.
12
+ module Broadcast
13
+ include ActionCable::Event
14
+
15
+ EVENT_NAME = 'broadcast.action_cable'.freeze
16
+
17
+ module_function
18
+
19
+ def event_name
20
+ self::EVENT_NAME
21
+ end
22
+
23
+ def span_name
24
+ Ext::SPAN_BROADCAST
25
+ end
26
+
27
+ def span_type
28
+ # Starts a broadcast of messages over WebSockets
29
+ Datadog::Ext::AppTypes::WEB
30
+ end
31
+
32
+ def process(span, _event, _id, payload)
33
+ channel = payload[:broadcasting] # Channel has high cardinality
34
+ span.service = configuration[:service_name]
35
+ span.span_type = span_type
36
+
37
+ # Set analytics sample rate
38
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
39
+ Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
40
+ end
41
+
42
+ span.set_tag(Ext::TAG_CHANNEL, channel)
43
+ span.set_tag(Ext::TAG_BROADCAST_CODER, payload[:coder])
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,52 @@
1
+ require 'ddtrace/contrib/analytics'
2
+ require 'ddtrace/contrib/action_cable/event'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActionCable
7
+ module Events
8
+ # Defines instrumentation for 'perform_action.action_cable' event.
9
+ #
10
+ # An action, triggered by a WebSockets client, invokes a method
11
+ # in the server's channel instance.
12
+ module PerformAction
13
+ include ActionCable::RootContextEvent
14
+
15
+ EVENT_NAME = 'perform_action.action_cable'.freeze
16
+
17
+ module_function
18
+
19
+ def event_name
20
+ self::EVENT_NAME
21
+ end
22
+
23
+ def span_name
24
+ Ext::SPAN_ACTION
25
+ end
26
+
27
+ def span_type
28
+ # A request to perform_action comes from a WebSocket connection
29
+ Datadog::Ext::AppTypes::WEB
30
+ end
31
+
32
+ def process(span, _event, _id, payload)
33
+ channel_class = payload[:channel_class]
34
+ action = payload[:action]
35
+
36
+ span.service = configuration[:service_name]
37
+ span.resource = "#{channel_class}##{action}"
38
+ span.span_type = span_type
39
+
40
+ # Set analytics sample rate
41
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
42
+ Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
43
+ end
44
+
45
+ span.set_tag(Ext::TAG_CHANNEL_CLASS, channel_class)
46
+ span.set_tag(Ext::TAG_ACTION, action)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,50 @@
1
+ require 'ddtrace/contrib/analytics'
2
+ require 'ddtrace/contrib/action_cable/event'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActionCable
7
+ module Events
8
+ # Defines instrumentation for 'transmit.action_cable' event.
9
+ #
10
+ # A 'transmit' event sends a message to a single client subscribed to a channel.
11
+ module Transmit
12
+ include ActionCable::Event
13
+
14
+ EVENT_NAME = 'transmit.action_cable'.freeze
15
+
16
+ module_function
17
+
18
+ def event_name
19
+ self::EVENT_NAME
20
+ end
21
+
22
+ def span_name
23
+ Ext::SPAN_TRANSMIT
24
+ end
25
+
26
+ def span_type
27
+ # ActionCable transmits data over WebSockets
28
+ Datadog::Ext::AppTypes::WEB
29
+ end
30
+
31
+ def process(span, _event, _id, payload)
32
+ channel_class = payload[:channel_class]
33
+
34
+ span.service = configuration[:service_name]
35
+ span.resource = channel_class
36
+ span.span_type = span_type
37
+
38
+ # Set analytics sample rate
39
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
40
+ Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
41
+ end
42
+
43
+ span.set_tag(Ext::TAG_CHANNEL_CLASS, channel_class)
44
+ span.set_tag(Ext::TAG_TRANSMIT_VIA, payload[:via])
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ module Datadog
2
+ module Contrib
3
+ module ActionCable
4
+ # ActionCable integration constants
5
+ module Ext
6
+ APP = 'action_cable'.freeze
7
+ ENV_ANALYTICS_ENABLED = 'DD_ACTION_CABLE_ANALYTICS_ENABLED'.freeze
8
+ ENV_ANALYTICS_SAMPLE_RATE = 'DD_ACTION_CABLE_ANALYTICS_SAMPLE_RATE'.freeze
9
+ SERVICE_NAME = 'action_cable'.freeze
10
+ SPAN_ACTION = 'action_cable.action'.freeze
11
+ SPAN_BROADCAST = 'action_cable.broadcast'.freeze
12
+ SPAN_ON_OPEN = 'action_cable.on_open'.freeze
13
+ SPAN_TRANSMIT = 'action_cable.transmit'.freeze
14
+ TAG_ACTION = 'action_cable.action'.freeze
15
+ TAG_BROADCAST_CODER = 'action_cable.broadcast.coder'.freeze
16
+ TAG_CHANNEL = 'action_cable.channel'.freeze
17
+ TAG_CHANNEL_CLASS = 'action_cable.channel_class'.freeze
18
+ TAG_CONNECTION = 'action_cable.connection'.freeze
19
+ TAG_TRANSMIT_VIA = 'action_cable.transmit.via'.freeze
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,31 @@
1
+ module Datadog
2
+ module Contrib
3
+ module ActionCable
4
+ module Instrumentation
5
+ # When a new WebSocket is open, we receive a Rack request resource name "GET -1".
6
+ # This module overrides the current Rack resource name to provide a meaningful name.
7
+ module ActionCableConnection
8
+ def on_open
9
+ Datadog.tracer.trace(Ext::SPAN_ON_OPEN) do |span|
10
+ begin
11
+ span.resource = "#{self.class}#on_open"
12
+ span.span_type = Datadog::Ext::AppTypes::WEB
13
+
14
+ span.set_tag(Ext::TAG_ACTION, 'on_open')
15
+ span.set_tag(Ext::TAG_CONNECTION, self.class.to_s)
16
+
17
+ # Set the resource name of the Rack request span
18
+ rack_request_span = env[Datadog::Contrib::Rack::TraceMiddleware::RACK_REQUEST_SPAN]
19
+ rack_request_span.resource = span.resource if rack_request_span
20
+ rescue StandardError => e
21
+ Datadog::Tracer.log.error("Error preparing span for ActionCable::Connection: #{e}")
22
+ end
23
+
24
+ super
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,36 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/action_cable/configuration/settings'
3
+ require 'ddtrace/contrib/action_cable/patcher'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module ActionCable
8
+ # Description of ActionCable integration
9
+ class Integration
10
+ include Contrib::Integration
11
+
12
+ register_as :action_cable, auto_patch: false
13
+
14
+ def self.version
15
+ Gem.loaded_specs['actioncable'] && Gem.loaded_specs['actioncable'].version
16
+ end
17
+
18
+ def self.present?
19
+ super && defined?(::ActionCable)
20
+ end
21
+
22
+ def self.compatible?
23
+ super && Rails::Integration.compatible?
24
+ end
25
+
26
+ def default_configuration
27
+ Configuration::Settings.new
28
+ end
29
+
30
+ def patcher
31
+ Patcher
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/ext/app_types'
3
+ require 'ddtrace/contrib/action_cable/ext'
4
+ require 'ddtrace/contrib/action_cable/events'
5
+ require 'ddtrace/contrib/action_cable/instrumentation'
6
+
7
+ module Datadog
8
+ module Contrib
9
+ module ActionCable
10
+ # Patcher enables patching of 'action_cable' module.
11
+ module Patcher
12
+ include Contrib::Patcher
13
+
14
+ module_function
15
+
16
+ def target_version
17
+ Integration.version
18
+ end
19
+
20
+ def patch
21
+ Events.subscribe!
22
+ ::ActionCable::Connection::Base.prepend(Instrumentation::ActionCableConnection)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end