hoodoo 1.15.1 → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/hoodoo/client/endpoint/endpoints/amqp.rb +1 -0
- data/lib/hoodoo/monkey.rb +1 -0
- data/lib/hoodoo/monkey/patch/datadog_traced_amqp.rb +89 -0
- data/lib/hoodoo/version.rb +1 -1
- data/spec/ddtrace.rb +17 -0
- data/spec/monkey/patch/datadog_traced_amqp_spec.rb +63 -0
- data/spec/services/middleware/middleware_exotic_communication_spec.rb +1 -0
- data/spec/services/middleware/middleware_multi_local_spec.rb +2 -2
- data/spec/shared_examples/middleware_amqp.rb +4 -2
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ab07823823bf92d1cfdd5070eb71585b95d7adbe
|
4
|
+
data.tar.gz: a9249d7aa4765ca5979eee0cf58d6919fc6f8a27
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fe35486b496e980d15d58cb2c353b86692833612a89cee9349b00bfac3fe5e54ae6cdb2fcd2591dd99454d66034e13b7fce01c6234c05ef0f5bcb7ea9dd0da1
|
7
|
+
data.tar.gz: 7101a2bc7914f19ab92fc338a74c16cb3f045b8d39985137dc177aae2bc1eb256a9f9af812be3eecd6eab78c2654302f853033c8bbf2bb88f7ab23e3767192fd
|
@@ -122,6 +122,7 @@ module Hoodoo
|
|
122
122
|
#
|
123
123
|
# * Hoodoo::Monkey
|
124
124
|
# * Hoodoo::Monkey::Patch::NewRelicTracedAMQP
|
125
|
+
# * Hoodoo::Monkey::Patch::DatadogTracedAMQP
|
125
126
|
#
|
126
127
|
# +http_message+:: Hash describing the message to send.
|
127
128
|
# +full_uri+:: Equivalent full URI of the request (information
|
data/lib/hoodoo/monkey.rb
CHANGED
@@ -0,0 +1,89 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: datadog_traced_amqp.rb
|
3
|
+
# (C):: Loyalty New Zealand 2017
|
4
|
+
#
|
5
|
+
# Purpose:: Extend the AMQP endpoint to support Datadog cross-app
|
6
|
+
# transaction tracing. Only defined and registered if the
|
7
|
+
# Datadog gem is available and Hoodooo Client is in scope.
|
8
|
+
#
|
9
|
+
# See Hoodoo::Monkey::Patch::DatadogTracedAMQP for more.
|
10
|
+
# ----------------------------------------------------------------------
|
11
|
+
# 22-June-2017 (JRW): Created.
|
12
|
+
########################################################################
|
13
|
+
|
14
|
+
module Hoodoo
|
15
|
+
module Monkey
|
16
|
+
module Patch
|
17
|
+
|
18
|
+
begin
|
19
|
+
require 'ddtrace' # Raises LoadError if Datadog is absent
|
20
|
+
|
21
|
+
# Wrap Hoodoo::Client::Endpoint::AMQP using Datadog transaction
|
22
|
+
# tracing so that over-queue inter-resource calls get connected
|
23
|
+
# together in Datadogs's view of the world.
|
24
|
+
#
|
25
|
+
# This module self-registers with Hooodoo::Monkey and, provided
|
26
|
+
# that Hoodoo::Services::Middleware is defined at parse-time,
|
27
|
+
# will be enabled by default.
|
28
|
+
#
|
29
|
+
module DatadogTracedAMQP
|
30
|
+
|
31
|
+
# Instance methods to patch over Hoodoo::Client::Endpoint::AMQP.
|
32
|
+
#
|
33
|
+
module InstanceExtensions
|
34
|
+
|
35
|
+
# Wrap the request with Datadog's distributed tracing.
|
36
|
+
# This adds headers to the request and extracts header data from
|
37
|
+
# the response. It calls the original implementation via +super+.
|
38
|
+
#
|
39
|
+
# +http_message+:: Hash describing the message to send.
|
40
|
+
#
|
41
|
+
# +full_uri+:: URI being sent to. This is somewhat meaningless
|
42
|
+
# when using AMQP but NewRelic requires it.
|
43
|
+
#
|
44
|
+
def monkey_send_request( http_message, full_uri )
|
45
|
+
amqp_response = nil
|
46
|
+
|
47
|
+
Datadog.tracer.trace( 'alchemy.request' ) do |span|
|
48
|
+
span.service = 'alchemy'
|
49
|
+
span.span_type = 'alchemy'
|
50
|
+
span.resource = http_message[ 'verb' ]
|
51
|
+
span.set_tag( 'target.path', http_message[ 'path'] )
|
52
|
+
|
53
|
+
# Add Datadog trace IDs to the HTTP message
|
54
|
+
http_message[ 'headers' ][ 'X_DDTRACE_PARENT_TRACE_ID' ] = span.trace_id.to_s
|
55
|
+
http_message[ 'headers' ][ 'X_DDTRACE_PARENT_SPAN_ID' ] = span.span_id.to_s
|
56
|
+
|
57
|
+
amqp_response = super( http_message, full_uri )
|
58
|
+
end
|
59
|
+
|
60
|
+
return amqp_response
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Register this class with the Hoodoo monkey patch engine.
|
66
|
+
#
|
67
|
+
if defined?( Hoodoo::Client ) &&
|
68
|
+
defined?( Hoodoo::Client::Endpoint ) &&
|
69
|
+
defined?( Hoodoo::Client::Endpoint::AMQP )
|
70
|
+
|
71
|
+
Hoodoo::Monkey.register(
|
72
|
+
target_unit: Hoodoo::Client::Endpoint::AMQP,
|
73
|
+
extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP
|
74
|
+
)
|
75
|
+
|
76
|
+
if defined?( Hoodoo::Services ) &&
|
77
|
+
defined?( Hoodoo::Services::Middleware )
|
78
|
+
|
79
|
+
Hoodoo::Monkey.enable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
rescue LoadError
|
84
|
+
# No Datadog => do nothing
|
85
|
+
end
|
86
|
+
|
87
|
+
end # module Patch
|
88
|
+
end # module Monkey
|
89
|
+
end # module Hoodoo
|
data/lib/hoodoo/version.rb
CHANGED
data/spec/ddtrace.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: ddtrace.rb
|
3
|
+
# (C):: Loyalty New Zealand 2017
|
4
|
+
#
|
5
|
+
# Purpose:: Override Datadog 'require "ddtrace"'. The test suite
|
6
|
+
# cannot allow "real" Datadog to be loaded as this would hook
|
7
|
+
# into all kinds of things and interfere with test results,
|
8
|
+
# especially for tests covering variant behaviour for when
|
9
|
+
# Datadog is present or absent.
|
10
|
+
# ----------------------------------------------------------------------
|
11
|
+
# 22-June-2017 (JRW): Created.
|
12
|
+
########################################################################
|
13
|
+
|
14
|
+
# Yes, this is empty, just comments. The whole point is to allow code to
|
15
|
+
# be able to require what it thinks is Datadog without a LoadError
|
16
|
+
# exception being raised, but not actually define any Datadog components
|
17
|
+
# until the test suite is good and ready to do so (with mock data).
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
# We need to run these tests in order. First a bunch of shared examples
|
4
|
+
# run. Then we check to see if hook methods were invoked in passing. You
|
5
|
+
# can't do that in an 'after' hook as exceptions therein cause warnings
|
6
|
+
# to be printed, but don't cause test failures.
|
7
|
+
#
|
8
|
+
describe Hoodoo::Monkey::Patch::DatadogTracedAMQP, :order => :defined do
|
9
|
+
|
10
|
+
# Not every test in the 'an AMQP-based middleware/client endpoint' shared
|
11
|
+
# example group will provoke a request. We cannot expect to have the
|
12
|
+
# NewRelic hooks called for every example. We *can* expect them to be
|
13
|
+
# called several times though, so use 'allow' to track those calls and
|
14
|
+
# count them.
|
15
|
+
#
|
16
|
+
before :all do
|
17
|
+
@@endpoint_do_amqp_count = 0
|
18
|
+
@@datadog_trace_count = 0
|
19
|
+
|
20
|
+
# Stub Datadog
|
21
|
+
class Datadog
|
22
|
+
def self.tracer
|
23
|
+
Datadog.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
Hoodoo::Monkey.enable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
|
28
|
+
end
|
29
|
+
|
30
|
+
after :all do
|
31
|
+
Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
|
32
|
+
Object.send( :remove_const, :Datadog )
|
33
|
+
end
|
34
|
+
|
35
|
+
before :each do
|
36
|
+
expect( Hoodoo::Client::Endpoint::AMQP.ancestors ).to include( Hoodoo::Monkey::Patch::DatadogTracedAMQP::InstanceExtensions )
|
37
|
+
|
38
|
+
original_do_amqp = Hoodoo::Client::Endpoint::AMQP.instance_method( :do_amqp )
|
39
|
+
|
40
|
+
allow_any_instance_of( Hoodoo::Client::Endpoint::AMQP ).to receive( :do_amqp ) do | instance, description_of_request |
|
41
|
+
result = original_do_amqp.bind( instance ).call( description_of_request )
|
42
|
+
@@endpoint_do_amqp_count += 1
|
43
|
+
result
|
44
|
+
end
|
45
|
+
|
46
|
+
allow_any_instance_of( Datadog ).to receive( :trace ) do | &block |
|
47
|
+
# Datadog Trace method responds with a yielded span this is here to mock tha
|
48
|
+
span = double('span', trace_id: 'trace_id', span_id: 'span_id').as_null_object
|
49
|
+
@@datadog_trace_count += 1
|
50
|
+
block.call(span)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it_behaves_like 'an AMQP-based middleware/client endpoint',
|
55
|
+
{'X_DDTRACE_PARENT_TRACE_ID'=>'trace_id', 'X_DDTRACE_PARENT_SPAN_ID' => 'span_id'}
|
56
|
+
|
57
|
+
context 'afterwards' do
|
58
|
+
it 'has non-zero NewRelic method call counts' do
|
59
|
+
expect( @@endpoint_do_amqp_count ).to be > 5
|
60
|
+
expect( @@datadog_trace_count ).to eq( @@endpoint_do_amqp_count )
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -8,6 +8,7 @@ describe Hoodoo::Services::Middleware do
|
|
8
8
|
|
9
9
|
context 'on queue' do
|
10
10
|
before :all do
|
11
|
+
Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::DatadogTracedAMQP )
|
11
12
|
Hoodoo::Monkey.disable( extension_module: Hoodoo::Monkey::Patch::NewRelicTracedAMQP )
|
12
13
|
end
|
13
14
|
|
@@ -437,8 +437,8 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
|
|
437
437
|
it 'manages ActiveRecord when implementation is called in its presence' do
|
438
438
|
pool = ActiveRecord::Base.connection_pool
|
439
439
|
|
440
|
-
expect( ActiveRecord::Base ).to receive( :connection_pool ).
|
441
|
-
expect( pool ).to receive( :with_connection ).
|
440
|
+
expect( ActiveRecord::Base ).to receive( :connection_pool ).exactly( 3 ).times.and_call_original
|
441
|
+
expect( pool ).to receive( :with_connection ).exactly( 2 ).times.and_call_original
|
442
442
|
|
443
443
|
list_things()
|
444
444
|
end
|
@@ -16,8 +16,10 @@ class RSpecTestServiceExoticStub < Hoodoo::Services::Service
|
|
16
16
|
comprised_of RSpecTestServiceExoticStubInterface
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
# Optional extra header hash is for middleware that intentionally adds headers
|
20
|
+
shared_examples 'an AMQP-based middleware/client endpoint' do |optional_extra_header_hash|
|
20
21
|
before :each do
|
22
|
+
@optional_extra_header_hash = optional_extra_header_hash || {}
|
21
23
|
@old_queue = ENV[ 'AMQ_URI' ]
|
22
24
|
ENV[ 'AMQ_URI' ] = 'amqp://test:test@127.0.0.1'
|
23
25
|
@mw = Hoodoo::Services::Middleware.new( RSpecTestServiceExoticStub.new )
|
@@ -103,7 +105,7 @@ shared_examples 'an AMQP-based middleware/client endpoint' do
|
|
103
105
|
'Accept-Language' => 'fr',
|
104
106
|
'X-Interaction-ID' => @interaction.interaction_id,
|
105
107
|
'X-Session-ID' => @interaction.context.session.session_id
|
106
|
-
},
|
108
|
+
}.merge!( @optional_extra_header_hash ),
|
107
109
|
} )
|
108
110
|
end.and_return( mock_response )
|
109
111
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hoodoo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Loyalty New Zealand
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-06-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dalli
|
@@ -156,14 +156,14 @@ dependencies:
|
|
156
156
|
requirements:
|
157
157
|
- - "~>"
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 1.
|
159
|
+
version: '1.6'
|
160
160
|
type: :development
|
161
161
|
prerelease: false
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
163
163
|
requirements:
|
164
164
|
- - "~>"
|
165
165
|
- !ruby/object:Gem::Version
|
166
|
-
version: 1.
|
166
|
+
version: '1.6'
|
167
167
|
- !ruby/object:Gem::Dependency
|
168
168
|
name: pg
|
169
169
|
requirement: !ruby/object:Gem::Requirement
|
@@ -317,6 +317,7 @@ files:
|
|
317
317
|
- lib/hoodoo/middleware.rb
|
318
318
|
- lib/hoodoo/monkey.rb
|
319
319
|
- lib/hoodoo/monkey/monkey.rb
|
320
|
+
- lib/hoodoo/monkey/patch/datadog_traced_amqp.rb
|
320
321
|
- lib/hoodoo/monkey/patch/newrelic_middleware_analytics.rb
|
321
322
|
- lib/hoodoo/monkey/patch/newrelic_traced_amqp.rb
|
322
323
|
- lib/hoodoo/presenters.rb
|
@@ -417,6 +418,7 @@ files:
|
|
417
418
|
- spec/data/types/permissions_full_spec.rb
|
418
419
|
- spec/data/types/permissions_resources_spec.rb
|
419
420
|
- spec/data/types/permissions_spec.rb
|
421
|
+
- spec/ddtrace.rb
|
420
422
|
- spec/errors/error_descriptions_spec.rb
|
421
423
|
- spec/errors/errors_spec.rb
|
422
424
|
- spec/files/regenerate.rb
|
@@ -428,6 +430,7 @@ files:
|
|
428
430
|
- spec/logger/writers/log_entries_dot_com_writer_spec.rb
|
429
431
|
- spec/logger/writers/stream_writer_spec.rb
|
430
432
|
- spec/monkey/monkey_spec.rb
|
433
|
+
- spec/monkey/patch/datadog_traced_amqp_spec.rb
|
431
434
|
- spec/monkey/patch/newrelic_middleware_analytics_spec.rb
|
432
435
|
- spec/monkey/patch/newrelic_traced_amqp_spec.rb
|
433
436
|
- spec/new_relic/agent/method_tracer.rb
|
@@ -560,6 +563,7 @@ test_files:
|
|
560
563
|
- spec/data/types/permissions_full_spec.rb
|
561
564
|
- spec/data/types/permissions_resources_spec.rb
|
562
565
|
- spec/data/types/permissions_spec.rb
|
566
|
+
- spec/ddtrace.rb
|
563
567
|
- spec/errors/error_descriptions_spec.rb
|
564
568
|
- spec/errors/errors_spec.rb
|
565
569
|
- spec/files/regenerate.rb
|
@@ -571,6 +575,7 @@ test_files:
|
|
571
575
|
- spec/logger/writers/log_entries_dot_com_writer_spec.rb
|
572
576
|
- spec/logger/writers/stream_writer_spec.rb
|
573
577
|
- spec/monkey/monkey_spec.rb
|
578
|
+
- spec/monkey/patch/datadog_traced_amqp_spec.rb
|
574
579
|
- spec/monkey/patch/newrelic_middleware_analytics_spec.rb
|
575
580
|
- spec/monkey/patch/newrelic_traced_amqp_spec.rb
|
576
581
|
- spec/new_relic/agent/method_tracer.rb
|