hoodoo 1.8.2 → 1.8.3
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
Mjk5NDIwYzU1NDI1ODFiYTcxM2FkYTBiZmQwOTg4NmJjMWJhYjFmOQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjhkNjVjZDMxYWE2NWZlZDNmMWI0ZjEyMTRiZmY0NjA0MDMyMTVlYQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjRjNzFlZTNhMmEyN2Y1NzQzNjQzYjc5NzUyNjJjNDRkZmEwZDE5NzIwMTY3
|
10
|
+
OTZhYWE3Mzk0MmQ1MzVlNDdiZjE1ZTc3MDUyOGQ2NDMyYTk4MDdmMzJlZGMz
|
11
|
+
NzQ3NWY1OTMzNGFlNDg1MDJjMTI0NDYwZTNmMzAzYmUwNjY5YTg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZjM5MjVjYmY4NDI2MjVjOTJmNzYxYWJiZWI0YjFkODUwMWNhNmE4NmUxMjNl
|
14
|
+
NzJmNjM1OTI5ODVmNzU1MjhkYWUzMDBlNThlZDBiZWNiMWNjN2VkY2E2Y2Vi
|
15
|
+
ZDRmMzU3M2Q0MWRiZDYwMzIzZGRmMzMzNDM3NTY0Y2Y4NWI2MGY=
|
data/lib/hoodoo/monkey.rb
CHANGED
@@ -0,0 +1,102 @@
|
|
1
|
+
########################################################################
|
2
|
+
# File:: newrelic_middleware_analytics.rb
|
3
|
+
# (C):: Loyalty New Zealand 2016
|
4
|
+
#
|
5
|
+
# Purpose:: Add custom attributes to NewRelic transactions and improve
|
6
|
+
# visibility over the time spent in implementations separately
|
7
|
+
# from the time spent in middleware.
|
8
|
+
#
|
9
|
+
# See Hoodoo::Monkey::Patch::NewRelicMiddlewareAnalytics for
|
10
|
+
# more.
|
11
|
+
# ----------------------------------------------------------------------
|
12
|
+
# 06-May-2016 (RJS): Created.
|
13
|
+
########################################################################
|
14
|
+
|
15
|
+
begin
|
16
|
+
# Raises LoadError if NewRelic is absent
|
17
|
+
require 'new_relic/agent/method_tracer'
|
18
|
+
|
19
|
+
# Add a method tracer on the dispatch method so that the time spent
|
20
|
+
# executing middleware can be distinguished from the time spent
|
21
|
+
# executing the service implementation.
|
22
|
+
#
|
23
|
+
module Hoodoo
|
24
|
+
module Services
|
25
|
+
class Middleware
|
26
|
+
include ::NewRelic::Agent::MethodTracer
|
27
|
+
|
28
|
+
add_method_tracer :dispatch, 'Custom/dispatch'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
rescue LoadError; end
|
33
|
+
|
34
|
+
module Hoodoo
|
35
|
+
module Monkey
|
36
|
+
module Patch
|
37
|
+
|
38
|
+
begin
|
39
|
+
require 'newrelic_rpm' # Raises LoadError if NewRelic is absent
|
40
|
+
|
41
|
+
# This module adds custom attributes to NewRelic transaction traces such
|
42
|
+
# that transactions can be filtered by target resource and request
|
43
|
+
# action.
|
44
|
+
#
|
45
|
+
# This module self-registers with Hooodoo::Monkey and, provided
|
46
|
+
# that Hoodoo::Services::Middleware is defined at parse-time,
|
47
|
+
# will be enabled by default.
|
48
|
+
#
|
49
|
+
module NewRelicMiddlewareAnalytics
|
50
|
+
|
51
|
+
# Instance methods to patch over Hoodoo::Services::Middleware.
|
52
|
+
#
|
53
|
+
module InstanceExtensions
|
54
|
+
|
55
|
+
# Add custom attributes to the NewRelic transaction. The original
|
56
|
+
# implementation is called via +super+.
|
57
|
+
#
|
58
|
+
# +interaction+:: Hoodoo::Services::Interaction describing the
|
59
|
+
# inbound request. The +interaction_id+,
|
60
|
+
# +rack_request+ and +session+ data is used (the
|
61
|
+
# latter being optional). If +target_interface+ and
|
62
|
+
# +requested_action+ are available, body data
|
63
|
+
# _might_ be logged according to secure log settings
|
64
|
+
# in the interface; if these values are unset, body
|
65
|
+
# data is _not_ logged.
|
66
|
+
#
|
67
|
+
def monkey_log_inbound_request( interaction )
|
68
|
+
|
69
|
+
# Add custom attributes to the NewRelic transaction.
|
70
|
+
::NewRelic::Agent.add_custom_attributes(
|
71
|
+
{
|
72
|
+
:target_action => interaction.requested_action,
|
73
|
+
:target_path => CGI.unescape( interaction.rack_request.path() )
|
74
|
+
}
|
75
|
+
)
|
76
|
+
|
77
|
+
# Call the original logging method.
|
78
|
+
super( interaction )
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
if defined?( Hoodoo::Services ) &&
|
86
|
+
defined?( Hoodoo::Services::Middleware )
|
87
|
+
|
88
|
+
::Hoodoo::Monkey.register(
|
89
|
+
target_unit: Hoodoo::Services::Middleware,
|
90
|
+
extension_module: Hoodoo::Monkey::Patch::NewRelicMiddlewareAnalytics
|
91
|
+
)
|
92
|
+
|
93
|
+
::Hoodoo::Monkey.enable( extension_module: Hoodoo::Monkey::Patch::NewRelicMiddlewareAnalytics )
|
94
|
+
end
|
95
|
+
|
96
|
+
rescue LoadError
|
97
|
+
# No NewRelic => do nothing
|
98
|
+
end
|
99
|
+
|
100
|
+
end # module Patch
|
101
|
+
end # module Monkey
|
102
|
+
end # module Hoodoo
|
@@ -413,7 +413,6 @@ module Hoodoo; module Services
|
|
413
413
|
service_container.is_a?( NewRelic::Agent::Instrumentation::MiddlewareProxy )
|
414
414
|
|
415
415
|
if service_container.respond_to?( :target )
|
416
|
-
newrelic_wrapper = service_container
|
417
416
|
service_container = service_container.target()
|
418
417
|
else
|
419
418
|
raise "Hoodoo::Services::Middleware instance created with NewRelic-wrapped Service entity, but NewRelic API is not as expected by Hoodoo; incompatible NewRelic version."
|
@@ -947,6 +946,80 @@ module Hoodoo; module Services
|
|
947
946
|
return result
|
948
947
|
end
|
949
948
|
|
949
|
+
# Make an "inbound" call log based on the given interaction.
|
950
|
+
#
|
951
|
+
# +interaction+:: Hoodoo::Services::Interaction describing the inbound
|
952
|
+
# request. The +interaction_id+, +rack_request+ and
|
953
|
+
# +session+ data is used (the latter being optional).
|
954
|
+
# If +target_interface+ and +requested_action+ are
|
955
|
+
# available, body data _might_ be logged according to
|
956
|
+
# secure log settings in the interface; if these
|
957
|
+
# values are unset, body data is _not_ logged.
|
958
|
+
#
|
959
|
+
def monkey_log_inbound_request( interaction )
|
960
|
+
|
961
|
+
data = build_common_log_data_for( interaction )
|
962
|
+
|
963
|
+
# Annoying dance required to extract all HTTP header data from Rack.
|
964
|
+
|
965
|
+
env = interaction.rack_request.env
|
966
|
+
headers = env.select do | key, value |
|
967
|
+
key.to_s.match( /^HTTP_/ )
|
968
|
+
end
|
969
|
+
|
970
|
+
headers[ 'CONTENT_TYPE' ] = env[ 'CONTENT_TYPE' ]
|
971
|
+
headers[ 'CONTENT_LENGTH' ] = env[ 'CONTENT_LENGTH' ]
|
972
|
+
|
973
|
+
data[ :payload ] = {
|
974
|
+
:method => env[ 'REQUEST_METHOD', ],
|
975
|
+
:scheme => env[ 'rack.url_scheme' ],
|
976
|
+
:host => env[ 'SERVER_NAME' ],
|
977
|
+
:port => env[ 'SERVER_PORT' ],
|
978
|
+
:script => env[ 'SCRIPT_NAME' ],
|
979
|
+
:path => env[ 'PATH_INFO' ],
|
980
|
+
:query => env[ 'QUERY_STRING' ],
|
981
|
+
:headers => headers
|
982
|
+
}
|
983
|
+
|
984
|
+
# Deal with body data and security issues.
|
985
|
+
|
986
|
+
secure = true
|
987
|
+
interface = interaction.target_interface
|
988
|
+
action = interaction.requested_action
|
989
|
+
|
990
|
+
unless interface.nil? || action.nil?
|
991
|
+
secure_log_actions = interface.secure_log_for()
|
992
|
+
secure_type = secure_log_actions[ action ]
|
993
|
+
|
994
|
+
# Allow body logging if there's no security specified for this action
|
995
|
+
# or the security is specified for the response only (since we log the
|
996
|
+
# request here).
|
997
|
+
#
|
998
|
+
# This means values of :both or :request will leave "secure" unchanged,
|
999
|
+
# as will any other unexpected value that might get specified.
|
1000
|
+
|
1001
|
+
secure = false if secure_type.nil? || secure_type == :response
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
# Compile the remaining log payload and send it.
|
1005
|
+
|
1006
|
+
unless secure
|
1007
|
+
body = interaction.rack_request.body.read( MAXIMUM_LOGGED_PAYLOAD_SIZE )
|
1008
|
+
interaction.rack_request.body.rewind()
|
1009
|
+
|
1010
|
+
data[ :payload ][ :body ] = body
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
@@logger.report(
|
1014
|
+
:info,
|
1015
|
+
:Middleware,
|
1016
|
+
:inbound,
|
1017
|
+
data
|
1018
|
+
)
|
1019
|
+
|
1020
|
+
return nil
|
1021
|
+
end
|
1022
|
+
|
950
1023
|
private
|
951
1024
|
|
952
1025
|
@@interfaces_have_public_methods = false
|
@@ -1111,80 +1184,6 @@ module Hoodoo; module Services
|
|
1111
1184
|
return data
|
1112
1185
|
end
|
1113
1186
|
|
1114
|
-
# Make an "inbound" call log based on the given interaction.
|
1115
|
-
#
|
1116
|
-
# +interaction+:: Hoodoo::Services::Interaction describing the inbound
|
1117
|
-
# request. The +interaction_id+, +rack_request+ and
|
1118
|
-
# +session+ data is used (the latter being optional).
|
1119
|
-
# If +target_interface+ and +requested_action+ are
|
1120
|
-
# available, body data _might_ be logged according to
|
1121
|
-
# secure log settings in the interface; if these
|
1122
|
-
# values are unset, body data is _not_ logged.
|
1123
|
-
#
|
1124
|
-
def log_inbound_request( interaction )
|
1125
|
-
|
1126
|
-
data = build_common_log_data_for( interaction )
|
1127
|
-
|
1128
|
-
# Annoying dance required to extract all HTTP header data from Rack.
|
1129
|
-
|
1130
|
-
env = interaction.rack_request.env
|
1131
|
-
headers = env.select do | key, value |
|
1132
|
-
key.to_s.match( /^HTTP_/ )
|
1133
|
-
end
|
1134
|
-
|
1135
|
-
headers[ 'CONTENT_TYPE' ] = env[ 'CONTENT_TYPE' ]
|
1136
|
-
headers[ 'CONTENT_LENGTH' ] = env[ 'CONTENT_LENGTH' ]
|
1137
|
-
|
1138
|
-
data[ :payload ] = {
|
1139
|
-
:method => env[ 'REQUEST_METHOD', ],
|
1140
|
-
:scheme => env[ 'rack.url_scheme' ],
|
1141
|
-
:host => env[ 'SERVER_NAME' ],
|
1142
|
-
:port => env[ 'SERVER_PORT' ],
|
1143
|
-
:script => env[ 'SCRIPT_NAME' ],
|
1144
|
-
:path => env[ 'PATH_INFO' ],
|
1145
|
-
:query => env[ 'QUERY_STRING' ],
|
1146
|
-
:headers => headers
|
1147
|
-
}
|
1148
|
-
|
1149
|
-
# Deal with body data and security issues.
|
1150
|
-
|
1151
|
-
secure = true
|
1152
|
-
interface = interaction.target_interface
|
1153
|
-
action = interaction.requested_action
|
1154
|
-
|
1155
|
-
unless interface.nil? || action.nil?
|
1156
|
-
secure_log_actions = interface.secure_log_for()
|
1157
|
-
secure_type = secure_log_actions[ action ]
|
1158
|
-
|
1159
|
-
# Allow body logging if there's no security specified for this action
|
1160
|
-
# or the security is specified for the response only (since we log the
|
1161
|
-
# request here).
|
1162
|
-
#
|
1163
|
-
# This means values of :both or :request will leave "secure" unchanged,
|
1164
|
-
# as will any other unexpected value that might get specified.
|
1165
|
-
|
1166
|
-
secure = false if secure_type.nil? || secure_type == :response
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
# Compile the remaining log payload and send it.
|
1170
|
-
|
1171
|
-
unless secure
|
1172
|
-
body = interaction.rack_request.body.read( MAXIMUM_LOGGED_PAYLOAD_SIZE )
|
1173
|
-
interaction.rack_request.body.rewind()
|
1174
|
-
|
1175
|
-
data[ :payload ][ :body ] = body
|
1176
|
-
end
|
1177
|
-
|
1178
|
-
@@logger.report(
|
1179
|
-
:info,
|
1180
|
-
:Middleware,
|
1181
|
-
:inbound,
|
1182
|
-
data
|
1183
|
-
)
|
1184
|
-
|
1185
|
-
return nil
|
1186
|
-
end
|
1187
|
-
|
1188
1187
|
# This is part of the formalised structured logging interface upon which
|
1189
1188
|
# external entites might depend. Change with care.
|
1190
1189
|
#
|
@@ -1637,7 +1636,7 @@ module Hoodoo; module Services
|
|
1637
1636
|
# order to give later processing stages a chance to determine if the
|
1638
1637
|
# body data could be safely logged (since it's useful to have). Thus,
|
1639
1638
|
# later processing stages will still need to make a call to
|
1640
|
-
# "
|
1639
|
+
# "monkey_log_inbound_request".
|
1641
1640
|
#
|
1642
1641
|
# +interaction+:: Hoodoo::Services::Middleware::Interaction instance
|
1643
1642
|
# describing the current interaction. Parts of this may
|
@@ -1657,7 +1656,7 @@ module Hoodoo; module Services
|
|
1657
1656
|
# target resource or action, so we won't accidentally log secure data in
|
1658
1657
|
# the inbound payload (if any).
|
1659
1658
|
|
1660
|
-
|
1659
|
+
monkey_log_inbound_request( interaction )
|
1661
1660
|
set_common_response_headers( interaction )
|
1662
1661
|
|
1663
1662
|
# Potential special-case early exit for CORS preflight.
|
@@ -1756,7 +1755,7 @@ module Hoodoo; module Services
|
|
1756
1755
|
# We finally have enough data to log the inbound call again, with body
|
1757
1756
|
# data included if allowed by the target resource.
|
1758
1757
|
|
1759
|
-
|
1758
|
+
monkey_log_inbound_request( interaction )
|
1760
1759
|
|
1761
1760
|
authorisation = determine_authorisation( interaction )
|
1762
1761
|
return if response.halt_processing?
|
@@ -1857,7 +1856,6 @@ module Hoodoo; module Services
|
|
1857
1856
|
|
1858
1857
|
# Set up some convenience variables
|
1859
1858
|
|
1860
|
-
interface = interaction.target_interface
|
1861
1859
|
implementation = interaction.target_implementation
|
1862
1860
|
action = interaction.requested_action
|
1863
1861
|
context = interaction.context
|
@@ -2831,7 +2829,7 @@ module Hoodoo; module Services
|
|
2831
2829
|
|
2832
2830
|
end
|
2833
2831
|
|
2834
|
-
rescue
|
2832
|
+
rescue
|
2835
2833
|
payload_hash = {}
|
2836
2834
|
interaction.context.response.errors.add_error( 'generic.malformed' )
|
2837
2835
|
|
data/lib/hoodoo/version.rb
CHANGED
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.8.
|
4
|
+
version: 1.8.3
|
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: 2016-05-
|
11
|
+
date: 2016-05-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kgio
|
@@ -330,6 +330,7 @@ files:
|
|
330
330
|
- lib/hoodoo/middleware.rb
|
331
331
|
- lib/hoodoo/monkey.rb
|
332
332
|
- lib/hoodoo/monkey/monkey.rb
|
333
|
+
- lib/hoodoo/monkey/patch/newrelic_middleware_analytics.rb
|
333
334
|
- lib/hoodoo/monkey/patch/newrelic_traced_amqp.rb
|
334
335
|
- lib/hoodoo/presenters.rb
|
335
336
|
- lib/hoodoo/presenters/base.rb
|