hoodoo 1.8.2 → 1.8.3
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
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
|