ddtrace 0.8.2 → 0.9.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 (46) hide show
  1. checksums.yaml +4 -4
  2. data/.env +3 -1
  3. data/.gitignore +1 -0
  4. data/Appraisals +10 -0
  5. data/Rakefile +27 -1
  6. data/ddtrace.gemspec +2 -2
  7. data/docker-compose.yml +10 -0
  8. data/docs/GettingStarted.md +119 -0
  9. data/gemfiles/contrib.gemfile +5 -0
  10. data/gemfiles/contrib_old.gemfile +4 -0
  11. data/lib/ddtrace.rb +4 -11
  12. data/lib/ddtrace/buffer.rb +14 -0
  13. data/lib/ddtrace/contrib/aws/instrumentation.rb +43 -0
  14. data/lib/ddtrace/contrib/aws/parsed_context.rb +56 -0
  15. data/lib/ddtrace/contrib/aws/patcher.rb +56 -0
  16. data/lib/ddtrace/contrib/aws/services.rb +115 -0
  17. data/lib/ddtrace/contrib/dalli/instrumentation.rb +35 -0
  18. data/lib/ddtrace/contrib/dalli/patcher.rb +50 -0
  19. data/lib/ddtrace/contrib/dalli/quantize.rb +17 -0
  20. data/lib/ddtrace/contrib/faraday/middleware.rb +75 -0
  21. data/lib/ddtrace/contrib/faraday/patcher.rb +52 -0
  22. data/lib/ddtrace/contrib/mongodb/parsers.rb +57 -0
  23. data/lib/ddtrace/contrib/mongodb/patcher.rb +93 -0
  24. data/lib/ddtrace/contrib/mongodb/subscribers.rb +71 -0
  25. data/lib/ddtrace/contrib/rails/action_controller.rb +18 -19
  26. data/lib/ddtrace/contrib/rails/action_view.rb +51 -61
  27. data/lib/ddtrace/contrib/rails/active_support.rb +29 -73
  28. data/lib/ddtrace/contrib/rails/core_extensions.rb +191 -53
  29. data/lib/ddtrace/contrib/redis/quantize.rb +4 -6
  30. data/lib/ddtrace/contrib/resque/patcher.rb +38 -0
  31. data/lib/ddtrace/contrib/resque/resque_job.rb +31 -0
  32. data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +26 -0
  33. data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +60 -0
  34. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +50 -0
  35. data/lib/ddtrace/ext/http.rb +1 -0
  36. data/lib/ddtrace/ext/mongo.rb +12 -0
  37. data/lib/ddtrace/monkey.rb +18 -0
  38. data/lib/ddtrace/pipeline.rb +46 -0
  39. data/lib/ddtrace/pipeline/span_filter.rb +38 -0
  40. data/lib/ddtrace/pipeline/span_processor.rb +20 -0
  41. data/lib/ddtrace/tracer.rb +18 -0
  42. data/lib/ddtrace/utils.rb +23 -3
  43. data/lib/ddtrace/version.rb +2 -2
  44. data/lib/ddtrace/workers.rb +30 -22
  45. data/lib/ddtrace/writer.rb +5 -7
  46. metadata +30 -9
@@ -0,0 +1,56 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Aws
4
+ # A wrapper around Seahorse::Client::RequestContext
5
+ class ParsedContext
6
+ def initialize(context)
7
+ @context = context
8
+ end
9
+
10
+ def safely(attr, fallback = nil)
11
+ public_send(attr) rescue fallback
12
+ end
13
+
14
+ def resource
15
+ "#{service}.#{operation}"
16
+ end
17
+
18
+ def operation
19
+ context.operation_name
20
+ end
21
+
22
+ def status_code
23
+ context.http_response.status_code
24
+ end
25
+
26
+ def http_method
27
+ context.http_request.http_method
28
+ end
29
+
30
+ def region
31
+ context.client.config.region
32
+ end
33
+
34
+ def retry_attempts
35
+ context.retries
36
+ end
37
+
38
+ def path
39
+ context.http_request.endpoint.path
40
+ end
41
+
42
+ def host
43
+ context.http_request.endpoint.host
44
+ end
45
+
46
+ private
47
+
48
+ attr_reader :context
49
+
50
+ def service
51
+ context.client.class.to_s.split('::')[1].downcase
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,56 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Aws
4
+ SERVICE = 'aws'.freeze
5
+ AGENT = 'aws-sdk-ruby'.freeze
6
+ RESOURCE = 'aws.command'.freeze
7
+
8
+ # Responsible for hooking the instrumentation into aws-sdk
9
+ module Patcher
10
+ @patched = false
11
+
12
+ class << self
13
+ def patch
14
+ return @patched if patched? || !defined?(Seahorse::Client::Base)
15
+
16
+ require 'ddtrace/ext/app_types'
17
+ require 'ddtrace/contrib/aws/parsed_context'
18
+ require 'ddtrace/contrib/aws/instrumentation'
19
+ require 'ddtrace/contrib/aws/services'
20
+
21
+ add_pin
22
+ add_plugin(Seahorse::Client::Base, *loaded_constants)
23
+
24
+ @patched = true
25
+ rescue => e
26
+ Datadog::Tracer.log.error("Unable to apply AWS integration: #{e}")
27
+ @patched
28
+ end
29
+
30
+ def patched?
31
+ @patched
32
+ end
33
+
34
+ private
35
+
36
+ def add_pin
37
+ Pin.new(SERVICE, app_type: Ext::AppTypes::WEB).tap do |pin|
38
+ pin.onto(::Aws)
39
+ end
40
+ end
41
+
42
+ def add_plugin(*targets)
43
+ targets.each { |klass| klass.add_plugin(Instrumentation) }
44
+ end
45
+
46
+ def loaded_constants
47
+ SERVICES.each_with_object([]) do |service, constants|
48
+ next if ::Aws.autoload?(service)
49
+ constants << ::Aws.const_get(service).const_get(:Client) rescue next
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,115 @@
1
+ module Datadog
2
+ module Contrib
3
+ # rubocop:disable Metrics/ModuleLength:
4
+ module Aws
5
+ SERVICES = %w[
6
+ ACM
7
+ APIGateway
8
+ AppStream
9
+ ApplicationAutoScaling
10
+ ApplicationDiscoveryService
11
+ Athena
12
+ AutoScaling
13
+ Batch
14
+ Budgets
15
+ CloudDirectory
16
+ CloudFormation
17
+ CloudFront
18
+ CloudHSM
19
+ CloudHSMV2
20
+ CloudSearch
21
+ CloudSearchDomain
22
+ CloudTrail
23
+ CloudWatch
24
+ CloudWatchEvents
25
+ CloudWatchLogs
26
+ CodeBuild
27
+ CodeCommit
28
+ CodeDeploy
29
+ CodePipeline
30
+ CodeStar
31
+ CognitoIdentity
32
+ CognitoIdentityProvider
33
+ CognitoSync
34
+ ConfigService
35
+ CostandUsageReportService
36
+ DAX
37
+ DataPipeline
38
+ DatabaseMigrationService
39
+ DeviceFarm
40
+ DirectConnect
41
+ DirectoryService
42
+ DynamoDB
43
+ DynamoDBStreams
44
+ EC2
45
+ ECR
46
+ ECS
47
+ EFS
48
+ EMR
49
+ ElastiCache
50
+ ElasticBeanstalk
51
+ ElasticLoadBalancing
52
+ ElasticLoadBalancingV2
53
+ ElasticTranscoder
54
+ ElasticsearchService
55
+ Firehose
56
+ GameLift
57
+ Glacier
58
+ Glue
59
+ Greengrass
60
+ Health
61
+ IAM
62
+ ImportExport
63
+ Inspector
64
+ IoT
65
+ IoTDataPlane
66
+ KMS
67
+ Kinesis
68
+ KinesisAnalytics
69
+ Lambda
70
+ LambdaPreview
71
+ Lex
72
+ LexModelBuildingService
73
+ Lightsail
74
+ MTurk
75
+ MachineLearning
76
+ MarketplaceCommerceAnalytics
77
+ MarketplaceEntitlementService
78
+ MarketplaceMetering
79
+ MigrationHub
80
+ Mobile
81
+ OpsWorks
82
+ OpsWorksCM
83
+ Organizations
84
+ Pinpoint
85
+ Polly
86
+ RDS
87
+ Redshift
88
+ Rekognition
89
+ ResourceGroupsTaggingAPI
90
+ Route53
91
+ Route53Domains
92
+ S3
93
+ SES
94
+ SMS
95
+ SNS
96
+ SQS
97
+ SSM
98
+ STS
99
+ SWF
100
+ ServiceCatalog
101
+ Shield
102
+ SimpleDB
103
+ Snowball
104
+ States
105
+ StorageGateway
106
+ Support
107
+ WAF
108
+ WAFRegional
109
+ WorkDocs
110
+ WorkSpaces
111
+ XRay
112
+ ].freeze
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'quantize'
2
+ require 'ddtrace/ext/net'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Dalli
7
+ # Instruments every interaction with the memcached server
8
+ module Instrumentation
9
+ module_function
10
+
11
+ def patch!
12
+ ::Dalli::Server.class_eval do
13
+ alias_method :__request, :request
14
+
15
+ def request(op, *args)
16
+ pin = Datadog::Pin.get_from(::Dalli)
17
+
18
+ pin.tracer.trace(Datadog::Contrib::Dalli::NAME) do |span|
19
+ span.resource = op.to_s.upcase
20
+ span.service = pin.service
21
+ span.span_type = pin.app_type
22
+ span.set_tag(Datadog::Ext::NET::TARGET_HOST, hostname)
23
+ span.set_tag(Datadog::Ext::NET::TARGET_PORT, port)
24
+ cmd = Datadog::Contrib::Dalli::Quantize.format_command(op, args)
25
+ span.set_tag(Datadog::Contrib::Dalli::CMD_TAG, cmd)
26
+
27
+ __request(op, *args)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,50 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Dalli
4
+ COMPATIBLE_WITH = Gem::Version.new('2.0.0')
5
+ SERVICE = 'memcached'.freeze
6
+ NAME = 'memcached.command'.freeze
7
+ CMD_TAG = 'memcached.command'.freeze
8
+
9
+ # Responsible for hooking the instrumentation into `dalli`
10
+ module Patcher
11
+ @patched = false
12
+
13
+ class << self
14
+ def patch
15
+ return @patched if patched? || !compatible?
16
+
17
+ require 'ddtrace/ext/app_types'
18
+ require_relative 'instrumentation'
19
+
20
+ add_pin!
21
+ Instrumentation.patch!
22
+
23
+ @patched = true
24
+ rescue => e
25
+ Tracer.log.error("Unable to apply Dalli integration: #{e}")
26
+ @patched
27
+ end
28
+
29
+ def patched?
30
+ @patched
31
+ end
32
+
33
+ private
34
+
35
+ def compatible?
36
+ return unless defined?(::Dalli::VERSION)
37
+
38
+ Gem::Version.new(::Dalli::VERSION) > COMPATIBLE_WITH
39
+ end
40
+
41
+ def add_pin!
42
+ Pin.new(SERVICE, app_type: Ext::AppTypes::DB).tap do |pin|
43
+ pin.onto(::Dalli)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Dalli
4
+ # Quantize contains dalli-specic quantization tools.
5
+ module Quantize
6
+ MAX_CMD_LENGTH = 100
7
+
8
+ module_function
9
+
10
+ def format_command(operation, args)
11
+ command = [operation, *args].join(' ').strip
12
+ Utils.truncate(command, MAX_CMD_LENGTH)
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,75 @@
1
+ require 'faraday'
2
+ require 'ddtrace/ext/http'
3
+ require 'ddtrace/ext/net'
4
+ require 'ddtrace/ext/distributed'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module Faraday
9
+ # Middleware implements a faraday-middleware for ddtrace instrumentation
10
+ class Middleware < ::Faraday::Middleware
11
+ DEFAULT_ERROR_HANDLER = lambda do |env|
12
+ Ext::HTTP::ERROR_RANGE.cover?(env[:status])
13
+ end
14
+
15
+ DEFAULT_OPTIONS = {
16
+ distributed_tracing: false,
17
+ split_by_domain: false,
18
+ error_handler: DEFAULT_ERROR_HANDLER
19
+ }.freeze
20
+
21
+ def initialize(app, options = {})
22
+ super(app)
23
+ @options = DEFAULT_OPTIONS.merge(options)
24
+ end
25
+
26
+ def call(env)
27
+ dd_pin.tracer.trace(SERVICE) do |span|
28
+ annotate!(span, env)
29
+ propagate!(span, env) if options[:distributed_tracing]
30
+ app.call(env).on_complete { |resp| handle_response(span, resp) }
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :app, :options
37
+
38
+ def annotate!(span, env)
39
+ span.resource = env[:method].to_s.upcase
40
+ span.service = service_name(env)
41
+ span.span_type = Ext::HTTP::TYPE
42
+ span.set_tag(Ext::HTTP::URL, env[:url].path)
43
+ span.set_tag(Ext::HTTP::METHOD, env[:method].to_s.upcase)
44
+ span.set_tag(Ext::NET::TARGET_HOST, env[:url].host)
45
+ span.set_tag(Ext::NET::TARGET_PORT, env[:url].port)
46
+ end
47
+
48
+ def handle_response(span, env)
49
+ if options.fetch(:error_handler).call(env)
50
+ span.set_error(["Error #{env[:status]}", env[:body]])
51
+ end
52
+
53
+ span.set_tag(Ext::HTTP::STATUS_CODE, env[:status])
54
+ end
55
+
56
+ def propagate!(span, env)
57
+ env[:request_headers].merge!(
58
+ Ext::DistributedTracing::HTTP_HEADER_TRACE_ID => span.trace_id.to_s,
59
+ Ext::DistributedTracing::HTTP_HEADER_PARENT_ID => span.span_id.to_s
60
+ )
61
+ end
62
+
63
+ def dd_pin
64
+ Pin.get_from(::Faraday)
65
+ end
66
+
67
+ def service_name(env)
68
+ return env[:url].host if options[:split_by_domain]
69
+
70
+ dd_pin.service
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,52 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Faraday
4
+ COMPATIBLE_UNTIL = Gem::Version.new('1.0.0')
5
+ SERVICE = 'faraday-request'.freeze
6
+
7
+ # Responsible for hooking the instrumentation into faraday
8
+ module Patcher
9
+ @patched = false
10
+
11
+ class << self
12
+ def patch
13
+ return @patched if patched? || !compatible?
14
+
15
+ require 'ddtrace/ext/app_types'
16
+ require 'ddtrace/contrib/faraday/middleware'
17
+
18
+ add_pin
19
+ add_middleware
20
+
21
+ @patched = true
22
+ rescue => e
23
+ Tracer.log.error("Unable to apply Faraday integration: #{e}")
24
+ @patched
25
+ end
26
+
27
+ def patched?
28
+ @patched
29
+ end
30
+
31
+ private
32
+
33
+ def compatible?
34
+ return unless defined?(::Faraday::VERSION)
35
+
36
+ Gem::Version.new(::Faraday::VERSION) < COMPATIBLE_UNTIL
37
+ end
38
+
39
+ def add_pin
40
+ Pin.new(SERVICE, app_type: Ext::AppTypes::WEB).tap do |pin|
41
+ pin.onto(::Faraday)
42
+ end
43
+ end
44
+
45
+ def add_middleware
46
+ ::Faraday::Middleware.register_middleware(ddtrace: Middleware)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end