ddtrace 0.30.1 → 0.31.0

Sign up to get free protection for your applications and to get access to all the features.
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