gruf 1.2.7 → 2.0.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/CHANGELOG.md +11 -0
- data/README.md +98 -119
- data/bin/gruf +9 -3
- data/lib/gruf.rb +4 -4
- data/lib/gruf/configuration.rb +11 -20
- data/lib/gruf/controllers/base.rb +82 -0
- data/lib/gruf/controllers/request.rb +96 -0
- data/lib/gruf/controllers/service_binder.rb +86 -0
- data/lib/gruf/error.rb +9 -0
- data/lib/gruf/errors/helpers.rb +40 -0
- data/lib/gruf/{hooks → interceptors}/active_record/connection_reset.rb +4 -10
- data/lib/gruf/interceptors/authentication/basic.rb +80 -0
- data/lib/gruf/interceptors/base.rb +51 -0
- data/lib/gruf/{instrumentation/output_metadata_timer.rb → interceptors/context.rb} +25 -15
- data/lib/gruf/interceptors/instrumentation/output_metadata_timer.rb +59 -0
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/base.rb +15 -13
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/logstash.rb +15 -13
- data/lib/gruf/{instrumentation → interceptors/instrumentation}/request_logging/formatters/plain.rb +21 -19
- data/lib/gruf/interceptors/instrumentation/request_logging/interceptor.rb +191 -0
- data/lib/gruf/interceptors/instrumentation/statsd.rb +80 -0
- data/lib/gruf/interceptors/registry.rb +131 -0
- data/lib/gruf/{authentication/none.rb → interceptors/server_interceptor.rb} +8 -7
- data/lib/gruf/interceptors/timer.rb +79 -0
- data/lib/gruf/response.rb +1 -2
- data/lib/gruf/server.rb +40 -25
- data/lib/gruf/version.rb +1 -1
- metadata +19 -20
- data/lib/gruf/authentication.rb +0 -65
- data/lib/gruf/authentication/base.rb +0 -65
- data/lib/gruf/authentication/basic.rb +0 -74
- data/lib/gruf/authentication/strategies.rb +0 -107
- data/lib/gruf/hooks/base.rb +0 -66
- data/lib/gruf/hooks/registry.rb +0 -110
- data/lib/gruf/instrumentation/base.rb +0 -114
- data/lib/gruf/instrumentation/registry.rb +0 -104
- data/lib/gruf/instrumentation/request_context.rb +0 -82
- data/lib/gruf/instrumentation/request_logging/hook.rb +0 -185
- data/lib/gruf/instrumentation/statsd.rb +0 -80
- data/lib/gruf/service.rb +0 -333
@@ -1,104 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
-
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
-
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
-
#
|
9
|
-
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
-
# Software.
|
11
|
-
#
|
12
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
-
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
-
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
-
#
|
17
|
-
require_relative 'base'
|
18
|
-
require_relative 'statsd'
|
19
|
-
require_relative 'output_metadata_timer'
|
20
|
-
require_relative 'request_logging/hook'
|
21
|
-
|
22
|
-
module Gruf
|
23
|
-
module Instrumentation
|
24
|
-
##
|
25
|
-
# Registry of all hooks added
|
26
|
-
#
|
27
|
-
class Registry
|
28
|
-
##
|
29
|
-
# Error class that represents when a instrumentation strategy does not extend the base class
|
30
|
-
#
|
31
|
-
class StrategyDescendantError < StandardError; end
|
32
|
-
|
33
|
-
class << self
|
34
|
-
##
|
35
|
-
# Add an authentication strategy, either through a class or a block
|
36
|
-
#
|
37
|
-
# Gruf::Instrumentation::Registry.add(:my_instrumentor, MyInstrumentor)
|
38
|
-
#
|
39
|
-
# @param [String] name The name to represent the strategy as
|
40
|
-
# @param [Gruf::Hooks::Base|NilClass] strategy (Optional) The strategy class to add. If nil, will expect
|
41
|
-
# a block that can be built as a strategy instead
|
42
|
-
# @return [Class] The strategy that was added
|
43
|
-
#
|
44
|
-
def add(name, strategy = nil, &block)
|
45
|
-
base = Gruf::Instrumentation::Base
|
46
|
-
strategy ||= Class.new(base)
|
47
|
-
strategy.class_eval(&block) if block_given?
|
48
|
-
|
49
|
-
raise StrategyDescendantError, "Hooks must descend from #{base}" unless strategy.ancestors.include?(base)
|
50
|
-
|
51
|
-
_registry[name.to_sym] = strategy
|
52
|
-
end
|
53
|
-
|
54
|
-
##
|
55
|
-
# Return a strategy type registry via a hash accessor syntax
|
56
|
-
#
|
57
|
-
# @return [Gruf::Instrumentation::Base|NilClass] The requested strategy, if exists
|
58
|
-
#
|
59
|
-
def [](name)
|
60
|
-
_registry[name.to_sym]
|
61
|
-
end
|
62
|
-
|
63
|
-
##
|
64
|
-
# Iterate over each hook in the registry
|
65
|
-
#
|
66
|
-
def each
|
67
|
-
_registry.each do |name, s|
|
68
|
-
yield name, s
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
##
|
73
|
-
# @return [Hash<Class>] Return the registry represented as a Hash object
|
74
|
-
#
|
75
|
-
def to_h
|
76
|
-
_registry
|
77
|
-
end
|
78
|
-
|
79
|
-
##
|
80
|
-
# @return [Boolean] Return true if there are any registered instrumentation strategies
|
81
|
-
#
|
82
|
-
def any?
|
83
|
-
to_h.keys.count > 0
|
84
|
-
end
|
85
|
-
|
86
|
-
##
|
87
|
-
# @return [Hash] Clear all existing strategies from the registry
|
88
|
-
#
|
89
|
-
def clear
|
90
|
-
@_registry = {}
|
91
|
-
end
|
92
|
-
|
93
|
-
private
|
94
|
-
|
95
|
-
##
|
96
|
-
# @return [Hash<Class>] Return the current registry
|
97
|
-
#
|
98
|
-
def _registry
|
99
|
-
@_registry ||= {}
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
-
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
-
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
-
#
|
9
|
-
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
-
# Software.
|
11
|
-
#
|
12
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
-
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
-
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
-
#
|
17
|
-
module Gruf
|
18
|
-
module Instrumentation
|
19
|
-
##
|
20
|
-
# Represents a request context for a given incoming gRPC request. This represents an injection layer that is used
|
21
|
-
# to pass to instrumentation strategies safely across thread boundaries.
|
22
|
-
#
|
23
|
-
class RequestContext
|
24
|
-
# @return [Gruf::Service] service The service to instrument
|
25
|
-
attr_reader :service
|
26
|
-
# @return [Object] request The protobuf request object
|
27
|
-
attr_reader :request
|
28
|
-
# @return [Object] response The protobuf response object
|
29
|
-
attr_reader :response
|
30
|
-
# @return [Symbol] call_signature The gRPC method on the service that was called
|
31
|
-
attr_reader :call_signature
|
32
|
-
# @return [GRPC::ActiveCall] active_call The gRPC core active call object, which represents marshalled data for
|
33
|
-
# the call itself
|
34
|
-
attr_reader :active_call
|
35
|
-
# @return [Time] execution_time The execution time, in ms, of the request
|
36
|
-
attr_reader :execution_time
|
37
|
-
|
38
|
-
##
|
39
|
-
# Initialize the request context given the request and response
|
40
|
-
#
|
41
|
-
def initialize(
|
42
|
-
service:,
|
43
|
-
request:,
|
44
|
-
response:,
|
45
|
-
call_signature:,
|
46
|
-
active_call:,
|
47
|
-
execution_time: 0.00
|
48
|
-
)
|
49
|
-
@service = service
|
50
|
-
@request = request
|
51
|
-
@response = response
|
52
|
-
@call_signature = call_signature
|
53
|
-
@active_call = active_call
|
54
|
-
@execution_time = execution_time
|
55
|
-
end
|
56
|
-
|
57
|
-
##
|
58
|
-
# @return [Boolean] True if the response is successful
|
59
|
-
#
|
60
|
-
def success?
|
61
|
-
!response.is_a?(GRPC::BadStatus)
|
62
|
-
end
|
63
|
-
|
64
|
-
##
|
65
|
-
# @return [String] Return the response class name
|
66
|
-
#
|
67
|
-
def response_class_name
|
68
|
-
response.class.name
|
69
|
-
end
|
70
|
-
|
71
|
-
##
|
72
|
-
# Return the execution time rounded to a specified precision
|
73
|
-
#
|
74
|
-
# @param [Integer] precision The amount of decimal places to round to
|
75
|
-
# @return [Float] The execution time rounded to the appropriate decimal point
|
76
|
-
#
|
77
|
-
def execution_time_rounded(precision: 2)
|
78
|
-
execution_time.to_f.round(precision)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
@@ -1,185 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
-
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
-
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
-
#
|
9
|
-
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
-
# Software.
|
11
|
-
#
|
12
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
-
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
-
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
-
#
|
17
|
-
require 'socket'
|
18
|
-
require_relative 'formatters/base'
|
19
|
-
require_relative 'formatters/logstash'
|
20
|
-
require_relative 'formatters/plain'
|
21
|
-
|
22
|
-
module Gruf
|
23
|
-
module Instrumentation
|
24
|
-
module RequestLogging
|
25
|
-
##
|
26
|
-
# Represents an error if the formatter does not extend the base formatter
|
27
|
-
#
|
28
|
-
class InvalidFormatterError < StandardError; end
|
29
|
-
|
30
|
-
##
|
31
|
-
# Handles Rails-style request logging for gruf services.
|
32
|
-
#
|
33
|
-
# This is added by default to gruf servers; if you have `Gruf.use_default_hooks = false`, you can add it back
|
34
|
-
# manually by doing:
|
35
|
-
#
|
36
|
-
# Gruf::Instrumentation::Registry.add(:request_logging, Gruf::Instrumentation::RequestLogging::Hook)
|
37
|
-
#
|
38
|
-
class Hook < ::Gruf::Instrumentation::Base
|
39
|
-
|
40
|
-
###
|
41
|
-
# Log the request, sending it to the appropriate formatter
|
42
|
-
#
|
43
|
-
# @param [Gruf::Instrumentation::RequestContext] rc The current request context for the call
|
44
|
-
# @return [String]
|
45
|
-
#
|
46
|
-
def call(rc)
|
47
|
-
if rc.success?
|
48
|
-
type = :info
|
49
|
-
status_name = 'GRPC::Ok'
|
50
|
-
else
|
51
|
-
type = :error
|
52
|
-
status_name = rc.response_class_name
|
53
|
-
end
|
54
|
-
|
55
|
-
payload = {}
|
56
|
-
payload[:params] = sanitize(rc.request.to_h) if options.fetch(:log_parameters, false)
|
57
|
-
payload[:message] = message(rc)
|
58
|
-
payload[:service] = service_key
|
59
|
-
payload[:method] = rc.call_signature
|
60
|
-
payload[:action] = rc.call_signature
|
61
|
-
payload[:grpc_status] = status_name
|
62
|
-
payload[:duration] = rc.execution_time_rounded
|
63
|
-
payload[:status] = status(rc.response, rc.success?)
|
64
|
-
payload[:thread_id] = Thread.current.object_id
|
65
|
-
payload[:time] = Time.now.to_s
|
66
|
-
payload[:host] = Socket.gethostname
|
67
|
-
|
68
|
-
::Gruf.logger.send(type, formatter.format(payload))
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
##
|
74
|
-
# Return an appropriate log message dependent on the status
|
75
|
-
#
|
76
|
-
# @param [RequestContext] rc The current request context
|
77
|
-
# @return [String] The appropriate message body
|
78
|
-
#
|
79
|
-
def message(rc)
|
80
|
-
if rc.success?
|
81
|
-
"[GRPC::Ok] (#{service_key}.#{rc.call_signature})"
|
82
|
-
else
|
83
|
-
"[#{rc.response_class_name}] (#{service_key}.#{rc.call_signature}) #{rc.response.message}"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
##
|
88
|
-
# Return the proper status code for the response
|
89
|
-
#
|
90
|
-
# @param [Object] response The response object
|
91
|
-
# @param [Boolean] successful If the response was successful
|
92
|
-
# @return [Boolean] The proper status code
|
93
|
-
#
|
94
|
-
def status(response, successful)
|
95
|
-
successful ? GRPC::Core::StatusCodes::OK : response.code
|
96
|
-
end
|
97
|
-
|
98
|
-
##
|
99
|
-
# Determine the appropriate formatter for the request logging
|
100
|
-
#
|
101
|
-
# @return [Gruf::Instrumentation::RequestLogging::Formatters::Base]
|
102
|
-
#
|
103
|
-
def formatter
|
104
|
-
unless @formatter
|
105
|
-
fmt = options.fetch(:formatter, :plain)
|
106
|
-
@formatter = case fmt
|
107
|
-
when Symbol
|
108
|
-
klass = "Gruf::Instrumentation::RequestLogging::Formatters::#{fmt.to_s.capitalize}"
|
109
|
-
fmt = klass.constantize.new
|
110
|
-
when Class
|
111
|
-
fmt = fmt.new
|
112
|
-
else
|
113
|
-
fmt
|
114
|
-
end
|
115
|
-
raise Gruf::Instrumentation::RequestLogging::InvalidFormatterError unless fmt.is_a?(Gruf::Instrumentation::RequestLogging::Formatters::Base)
|
116
|
-
end
|
117
|
-
@formatter
|
118
|
-
end
|
119
|
-
|
120
|
-
##
|
121
|
-
# Redact any blacklisted params and return an updated hash
|
122
|
-
#
|
123
|
-
# @param [Hash] params The hash of parameters to sanitize
|
124
|
-
# @return [Hash] The sanitized params in hash form
|
125
|
-
#
|
126
|
-
def sanitize(params = {})
|
127
|
-
blacklists = options.fetch(:blacklist, []).map(&:to_s)
|
128
|
-
redacted_string = options.fetch(:redacted_string, 'REDACTED')
|
129
|
-
blacklists.each do |blacklist|
|
130
|
-
parts = blacklist.split('.').map(&:to_sym)
|
131
|
-
redact!(parts, 0, params, redacted_string)
|
132
|
-
end
|
133
|
-
params
|
134
|
-
end
|
135
|
-
|
136
|
-
##
|
137
|
-
# Fetch the options for this hook
|
138
|
-
#
|
139
|
-
# @return [Hash] Return a hash of options for this hook
|
140
|
-
#
|
141
|
-
def options
|
142
|
-
super().fetch(:request_logging, {})
|
143
|
-
end
|
144
|
-
|
145
|
-
##
|
146
|
-
# Helper method to recursively redact based on the black list
|
147
|
-
#
|
148
|
-
# @param [Array] parts The blacklist. ex. 'data.schema' -> [:data, :schema]
|
149
|
-
# @param [Integer] idx The current index of the blacklist
|
150
|
-
# @param [Hash] params The hash of parameters to sanitize
|
151
|
-
# @param [String] redacted_string The custom redact string
|
152
|
-
#
|
153
|
-
def redact!(parts = [], idx = 0, params = {}, redacted_string = 'REDACTED')
|
154
|
-
return unless parts.is_a?(Array) && params.is_a?(Hash)
|
155
|
-
return if idx >= parts.size || !params.key?(parts[idx])
|
156
|
-
if idx == parts.size - 1
|
157
|
-
if params[parts[idx]].is_a? Hash
|
158
|
-
hash_deep_redact!(params[parts[idx]], redacted_string)
|
159
|
-
else
|
160
|
-
params[parts[idx]] = redacted_string
|
161
|
-
end
|
162
|
-
return
|
163
|
-
end
|
164
|
-
redact!(parts, idx + 1, params[parts[idx]], redacted_string)
|
165
|
-
end
|
166
|
-
|
167
|
-
##
|
168
|
-
# Helper method to recursively redact the value of all hash keys
|
169
|
-
#
|
170
|
-
# @param [Hash] hash Part of the hash of parameters to sanitize
|
171
|
-
# @param [String] redacted_string The custom redact string
|
172
|
-
#
|
173
|
-
def hash_deep_redact!(hash, redacted_string)
|
174
|
-
hash.keys.each do |key|
|
175
|
-
if hash[key].is_a? Hash
|
176
|
-
hash_deep_redact!(hash[key], redacted_string)
|
177
|
-
else
|
178
|
-
hash[key] = redacted_string
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
# Copyright (c) 2017-present, BigCommerce Pty. Ltd. All rights reserved
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
5
|
-
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
6
|
-
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
7
|
-
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
8
|
-
#
|
9
|
-
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
10
|
-
# Software.
|
11
|
-
#
|
12
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
13
|
-
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
14
|
-
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
15
|
-
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
16
|
-
#
|
17
|
-
module Gruf
|
18
|
-
module Instrumentation
|
19
|
-
##
|
20
|
-
# Adds increment and timing stats to gRPC routes, pushing data to StatsD
|
21
|
-
#
|
22
|
-
class Statsd < Gruf::Instrumentation::Base
|
23
|
-
##
|
24
|
-
# Push data to StatsD, only doing so if a client is set
|
25
|
-
#
|
26
|
-
# @param [Gruf::Instrumentation::RequestContext] rc The current request context for the call
|
27
|
-
#
|
28
|
-
def call(rc)
|
29
|
-
if client
|
30
|
-
rk = route_key(rc.call_signature)
|
31
|
-
client.increment(rk)
|
32
|
-
client.increment("#{rk}.#{postfix(rc.success?)}")
|
33
|
-
client.timing(rk, rc.execution_time)
|
34
|
-
else
|
35
|
-
Gruf.logger.error 'Statsd module loaded, but no client configured!'
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
##
|
42
|
-
# @param [Boolean] successful Whether or not the request was successful
|
43
|
-
# @return [String] The appropriate postfix for the key dependent on response status
|
44
|
-
#
|
45
|
-
def postfix(successful)
|
46
|
-
successful ? 'success' : 'failure'
|
47
|
-
end
|
48
|
-
|
49
|
-
##
|
50
|
-
# @param [Symbol] call_signature The method call signature for the handler
|
51
|
-
# @return [String] Return a composed route key that is used in the statsd metric
|
52
|
-
#
|
53
|
-
def route_key(call_signature)
|
54
|
-
"#{key_prefix}#{method_key(call_signature)}"
|
55
|
-
end
|
56
|
-
|
57
|
-
##
|
58
|
-
# @return [String] Return the sanitized key prefix for the statsd metric key
|
59
|
-
#
|
60
|
-
def key_prefix
|
61
|
-
prefix = options.fetch(:prefix, '').to_s
|
62
|
-
prefix.empty? ? '' : "#{prefix}."
|
63
|
-
end
|
64
|
-
|
65
|
-
##
|
66
|
-
# @return [::Statsd] Return the given StatsD client
|
67
|
-
#
|
68
|
-
def client
|
69
|
-
@client ||= options.fetch(:client, nil)
|
70
|
-
end
|
71
|
-
|
72
|
-
##
|
73
|
-
# @return [Hash] Return a hash of options for this hook
|
74
|
-
#
|
75
|
-
def options
|
76
|
-
super().fetch(:statsd, {})
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|