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