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.
- checksums.yaml +4 -4
- data/.env +3 -1
- data/.gitignore +1 -0
- data/Appraisals +10 -0
- data/Rakefile +27 -1
- data/ddtrace.gemspec +2 -2
- data/docker-compose.yml +10 -0
- data/docs/GettingStarted.md +119 -0
- data/gemfiles/contrib.gemfile +5 -0
- data/gemfiles/contrib_old.gemfile +4 -0
- data/lib/ddtrace.rb +4 -11
- data/lib/ddtrace/buffer.rb +14 -0
- data/lib/ddtrace/contrib/aws/instrumentation.rb +43 -0
- data/lib/ddtrace/contrib/aws/parsed_context.rb +56 -0
- data/lib/ddtrace/contrib/aws/patcher.rb +56 -0
- data/lib/ddtrace/contrib/aws/services.rb +115 -0
- data/lib/ddtrace/contrib/dalli/instrumentation.rb +35 -0
- data/lib/ddtrace/contrib/dalli/patcher.rb +50 -0
- data/lib/ddtrace/contrib/dalli/quantize.rb +17 -0
- data/lib/ddtrace/contrib/faraday/middleware.rb +75 -0
- data/lib/ddtrace/contrib/faraday/patcher.rb +52 -0
- data/lib/ddtrace/contrib/mongodb/parsers.rb +57 -0
- data/lib/ddtrace/contrib/mongodb/patcher.rb +93 -0
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +71 -0
- data/lib/ddtrace/contrib/rails/action_controller.rb +18 -19
- data/lib/ddtrace/contrib/rails/action_view.rb +51 -61
- data/lib/ddtrace/contrib/rails/active_support.rb +29 -73
- data/lib/ddtrace/contrib/rails/core_extensions.rb +191 -53
- data/lib/ddtrace/contrib/redis/quantize.rb +4 -6
- data/lib/ddtrace/contrib/resque/patcher.rb +38 -0
- data/lib/ddtrace/contrib/resque/resque_job.rb +31 -0
- data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +26 -0
- data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +60 -0
- data/lib/ddtrace/contrib/sucker_punch/patcher.rb +50 -0
- data/lib/ddtrace/ext/http.rb +1 -0
- data/lib/ddtrace/ext/mongo.rb +12 -0
- data/lib/ddtrace/monkey.rb +18 -0
- data/lib/ddtrace/pipeline.rb +46 -0
- data/lib/ddtrace/pipeline/span_filter.rb +38 -0
- data/lib/ddtrace/pipeline/span_processor.rb +20 -0
- data/lib/ddtrace/tracer.rb +18 -0
- data/lib/ddtrace/utils.rb +23 -3
- data/lib/ddtrace/version.rb +2 -2
- data/lib/ddtrace/workers.rb +30 -22
- data/lib/ddtrace/writer.rb +5 -7
- 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
|