oboe 2.7.16.1-java → 2.7.17.1-java
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 +12 -0
- data/Gemfile +2 -0
- data/lib/oboe/config.rb +62 -13
- data/lib/oboe/inst/excon.rb +2 -1
- data/lib/oboe/inst/http.rb +8 -1
- data/lib/oboe/inst/httpclient.rb +173 -0
- data/lib/oboe/inst/rack.rb +6 -3
- data/lib/oboe/inst/typhoeus.rb +9 -5
- data/lib/oboe/util.rb +20 -0
- data/lib/oboe/version.rb +1 -1
- data/lib/rails/generators/oboe/templates/oboe_initializer.rb +33 -15
- data/test/instrumentation/excon_test.rb +66 -29
- data/test/instrumentation/faraday_test.rb +108 -63
- data/test/instrumentation/http_test.rb +63 -26
- data/test/instrumentation/httpclient_test.rb +296 -0
- data/test/instrumentation/rack_test.rb +40 -1
- data/test/instrumentation/rest-client_test.rb +65 -71
- data/test/instrumentation/typhoeus_test.rb +32 -25
- data/test/minitest_helper.rb +1 -0
- data/test/support/config_test.rb +52 -2
- metadata +30 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5af7c88e442b978109bfd9e26216d22ba96ebbc
|
4
|
+
data.tar.gz: 87967943c1a3c45db5e9576a9dd629eb4207254c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f534a642ed23073afa600719331797cfe7981d007918d18b172776e0a31783e260dc288bc3d7d8b507abae3abc51356f6581aa170af0cfa763bef5190fae9f8a
|
7
|
+
data.tar.gz: 2babaaa796835cc02dade64dd032ce6f154dbb491e25c54b7f34da1acaf604a06ccf9bac8a27eb8fa6ea0b97daf17999000ebf494e15046ae18c4c377e76f116
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,18 @@ https://github.com/appneta/oboe-ruby/releases
|
|
4
4
|
|
5
5
|
Dates in this file are in the format MM/DD/YYYY.
|
6
6
|
|
7
|
+
# oboe 2.7.17.1
|
8
|
+
|
9
|
+
This patch release includes:
|
10
|
+
|
11
|
+
* New config option to optionally not report URL query parameters: #116
|
12
|
+
* New HTTPClient instrumentation: #115
|
13
|
+
|
14
|
+
Pushed to Rubygems:
|
15
|
+
|
16
|
+
https://rubygems.org/gems/oboe/versions/2.7.17.1
|
17
|
+
https://rubygems.org/gems/oboe/versions/2.7.17.1-java
|
18
|
+
|
7
19
|
# oboe 2.7.16.1
|
8
20
|
|
9
21
|
This patch release includes:
|
data/Gemfile
CHANGED
@@ -3,6 +3,7 @@ source 'https://rubygems.org'
|
|
3
3
|
group :development, :test do
|
4
4
|
gem 'minitest', "5.5.1"
|
5
5
|
gem 'minitest-reporters'
|
6
|
+
gem 'minitest-debugger', :require => false
|
6
7
|
gem 'rack-test'
|
7
8
|
gem 'puma'
|
8
9
|
if RUBY_VERSION < '1.9.3'
|
@@ -38,6 +39,7 @@ gem 'mongo'
|
|
38
39
|
gem 'resque'
|
39
40
|
gem 'redis'
|
40
41
|
gem 'faraday'
|
42
|
+
gem 'httpclient'
|
41
43
|
gem 'excon'
|
42
44
|
gem 'typhoeus'
|
43
45
|
gem 'sequel'
|
data/lib/oboe/config.rb
CHANGED
@@ -13,9 +13,13 @@ module Oboe
|
|
13
13
|
|
14
14
|
@@instrumentation = [:action_controller, :action_view, :active_record,
|
15
15
|
:cassandra, :dalli, :em_http_request, :excon, :faraday,
|
16
|
-
:grape, :nethttp, :memcached, :memcache, :mongo,
|
16
|
+
:grape, :httpclient, :nethttp, :memcached, :memcache, :mongo,
|
17
17
|
:moped, :rack, :redis, :resque, :rest_client, :sequel,
|
18
18
|
:typhoeus]
|
19
|
+
|
20
|
+
# Subgrouping of instrumentation
|
21
|
+
@@http_clients = [:excon, :faraday, :httpclient, :nethttp, :rest_client, :typhoeus]
|
22
|
+
|
19
23
|
##
|
20
24
|
# Return the raw nested hash.
|
21
25
|
#
|
@@ -41,10 +45,11 @@ module Oboe
|
|
41
45
|
Oboe::Config[:action_view][:collect_backtraces] = true
|
42
46
|
Oboe::Config[:cassandra][:collect_backtraces] = true
|
43
47
|
Oboe::Config[:dalli][:collect_backtraces] = false
|
44
|
-
Oboe::Config[:faraday][:collect_backtraces] = false
|
45
|
-
Oboe::Config[:grape][:collect_backtraces] = true
|
46
48
|
Oboe::Config[:em_http_request][:collect_backtraces] = false
|
47
49
|
Oboe::Config[:excon][:collect_backtraces] = true
|
50
|
+
Oboe::Config[:faraday][:collect_backtraces] = false
|
51
|
+
Oboe::Config[:grape][:collect_backtraces] = true
|
52
|
+
Oboe::Config[:httpclient][:collect_backtraces] = true
|
48
53
|
Oboe::Config[:memcache][:collect_backtraces] = false
|
49
54
|
Oboe::Config[:memcached][:collect_backtraces] = false
|
50
55
|
Oboe::Config[:mongo][:collect_backtraces] = true
|
@@ -71,6 +76,33 @@ module Oboe
|
|
71
76
|
# Access Key is empty until loaded from config file or env var
|
72
77
|
@@config[:access_key] = ''
|
73
78
|
|
79
|
+
# Logging of outgoing HTTP query args
|
80
|
+
#
|
81
|
+
# This optionally disables the logging of query args of outgoing
|
82
|
+
# HTTP clients such as Net::HTTP, excon, typhoeus and others.
|
83
|
+
#
|
84
|
+
# This flag is global to all HTTP client instrumentation.
|
85
|
+
#
|
86
|
+
# To configure this on a per instrumentation basis, set this
|
87
|
+
# option to true and instead disable the instrumenstation specific
|
88
|
+
# option <tt>log_args</tt>:
|
89
|
+
#
|
90
|
+
# Oboe::Config[:nethttp][:log_args] = false
|
91
|
+
# Oboe::Config[:excon][:log_args] = false
|
92
|
+
# Oboe::Config[:typhoeus][:log_args] = true
|
93
|
+
#
|
94
|
+
@@config[:include_url_query_params] = true
|
95
|
+
|
96
|
+
# Logging of incoming HTTP query args
|
97
|
+
#
|
98
|
+
# This optionally disables the logging of incoming URL request
|
99
|
+
# query args.
|
100
|
+
#
|
101
|
+
# This flag is global and currently only affects the Rack
|
102
|
+
# instrumentation which reports incoming request URLs and
|
103
|
+
# query args by default.
|
104
|
+
@@config[:include_remote_url_params] = true
|
105
|
+
|
74
106
|
# The oboe Ruby client has the ability to sanitize query literals
|
75
107
|
# from SQL statements. By default this is disabled. Enable to
|
76
108
|
# avoid collecting and reporting query literals to TraceView.
|
@@ -110,6 +142,7 @@ module Oboe
|
|
110
142
|
# report all raised exception regardless.
|
111
143
|
@@config[:report_rescued_errors] = false
|
112
144
|
|
145
|
+
# Environment support for OpenShift.
|
113
146
|
if ENV.key?('OPENSHIFT_TRACEVIEW_TLYZER_IP')
|
114
147
|
# We're running on OpenShift
|
115
148
|
@@config[:tracing_mode] = 'always'
|
@@ -145,9 +178,8 @@ module Oboe
|
|
145
178
|
if key == :sampling_rate
|
146
179
|
Oboe.logger.warn 'sampling_rate is not a supported setting for Oboe::Config. ' \
|
147
180
|
'Please use :sample_rate.'
|
148
|
-
end
|
149
181
|
|
150
|
-
|
182
|
+
elsif key == :sample_rate
|
151
183
|
unless value.is_a?(Integer) || value.is_a?(Float)
|
152
184
|
fail 'oboe :sample_rate must be a number between 1 and 1000000 (1m)'
|
153
185
|
end
|
@@ -159,8 +191,19 @@ module Oboe
|
|
159
191
|
|
160
192
|
# Assure value is an integer
|
161
193
|
@@config[key.to_sym] = value.to_i
|
162
|
-
|
163
194
|
Oboe.set_sample_rate(value) if Oboe.loaded
|
195
|
+
|
196
|
+
elsif key == :include_url_query_params
|
197
|
+
# Obey the global flag and update all of the per instrumentation
|
198
|
+
# <tt>:log_args</tt> values.
|
199
|
+
@@http_clients.each do |i|
|
200
|
+
@@config[i][:log_args] = value
|
201
|
+
end
|
202
|
+
|
203
|
+
elsif key == :include_remote_url_params
|
204
|
+
# Obey the global flag and update all of the per instrumentation
|
205
|
+
# <tt>:log_args</tt> values.
|
206
|
+
@@config[:rack][:log_args] = value
|
164
207
|
end
|
165
208
|
|
166
209
|
# Update liboboe if updating :tracing_mode
|
@@ -169,18 +212,24 @@ module Oboe
|
|
169
212
|
end
|
170
213
|
end
|
171
214
|
|
172
|
-
def self.instrumentation_list
|
173
|
-
@@instrumentation
|
174
|
-
end
|
175
|
-
|
176
215
|
def self.method_missing(sym, *args)
|
216
|
+
class_var_name = "@@#{sym}"
|
217
|
+
|
177
218
|
if sym.to_s =~ /(.+)=$/
|
178
219
|
self[$1] = args.first
|
179
220
|
else
|
180
|
-
|
181
|
-
|
221
|
+
# Try part of the @@config hash first
|
222
|
+
if @@config.key?(sym)
|
223
|
+
self[sym]
|
224
|
+
|
225
|
+
# Then try as a class variable
|
226
|
+
elsif self.class_variable_defined?(class_var_name.to_sym)
|
227
|
+
self.class_eval(class_var_name)
|
228
|
+
|
229
|
+
# Congrats - You've won a brand new nil...
|
230
|
+
else
|
231
|
+
nil
|
182
232
|
end
|
183
|
-
self[sym]
|
184
233
|
end
|
185
234
|
end
|
186
235
|
end
|
data/lib/oboe/inst/excon.rb
CHANGED
@@ -15,7 +15,8 @@ module Oboe
|
|
15
15
|
kvs['RemoteProtocol'] = ::Oboe::Util.upcase(@data[:scheme])
|
16
16
|
kvs['RemoteHost'] = @data[:host]
|
17
17
|
|
18
|
-
|
18
|
+
# Conditionally log query args
|
19
|
+
if Oboe::Config[:excon][:log_args] && (@data[:query] && @data[:query].length)
|
19
20
|
kvs['ServiceArg'] = @data[:path] + '?' + @data[:query]
|
20
21
|
else
|
21
22
|
kvs['ServiceArg'] = @data[:path]
|
data/lib/oboe/inst/http.rb
CHANGED
@@ -29,7 +29,14 @@ if Oboe::Config[:nethttp][:enabled]
|
|
29
29
|
opts['IsService'] = 1
|
30
30
|
opts['RemoteProtocol'] = use_ssl? ? 'HTTPS' : 'HTTP'
|
31
31
|
opts['RemoteHost'] = addr_port
|
32
|
-
|
32
|
+
|
33
|
+
# Conditionally log query params
|
34
|
+
if Oboe::Config[:nethttp][:log_args]
|
35
|
+
opts['ServiceArg'] = req.path
|
36
|
+
else
|
37
|
+
opts['ServiceArg'] = req.path.split('?').first
|
38
|
+
end
|
39
|
+
|
33
40
|
opts['HTTPMethod'] = req.method
|
34
41
|
opts['Blacklisted'] = true if blacklisted
|
35
42
|
opts['Backtrace'] = Oboe::API.backtrace if Oboe::Config[:nethttp][:collect_backtraces]
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# Copyright (c) 2015 AppNeta, Inc.
|
2
|
+
# All rights reserved.
|
3
|
+
|
4
|
+
module Oboe
|
5
|
+
module Inst
|
6
|
+
module HTTPClient
|
7
|
+
def self.included(klass)
|
8
|
+
::Oboe::Util.method_alias(klass, :do_request, ::HTTPClient)
|
9
|
+
::Oboe::Util.method_alias(klass, :do_request_async, ::HTTPClient)
|
10
|
+
::Oboe::Util.method_alias(klass, :do_get_stream, ::HTTPClient)
|
11
|
+
end
|
12
|
+
|
13
|
+
def oboe_collect(method, uri, query = nil)
|
14
|
+
kvs = {}
|
15
|
+
kvs['IsService'] = 1
|
16
|
+
|
17
|
+
# Conditionally log URL query params
|
18
|
+
# Because of the hook points, the query arg can come in under <tt>query</tt>
|
19
|
+
# or as a part of <tt>uri</tt> (not both). Here we handle both cases.
|
20
|
+
if Oboe::Config[:httpclient][:log_args]
|
21
|
+
if query
|
22
|
+
kvs['RemoteURL'] = uri.to_s + '?' + Oboe::Util.to_query(query)
|
23
|
+
else
|
24
|
+
kvs['RemoteURL'] = uri.to_s
|
25
|
+
end
|
26
|
+
else
|
27
|
+
kvs['RemoteURL'] = uri.to_s.split('?').first
|
28
|
+
end
|
29
|
+
|
30
|
+
kvs['HTTPMethod'] = ::Oboe::Util.upcase(method)
|
31
|
+
kvs['Backtrace'] = Oboe::API.backtrace if Oboe::Config[:httpclient][:collect_backtraces]
|
32
|
+
kvs
|
33
|
+
rescue => e
|
34
|
+
Oboe.logger.debug "[oboe/debug] Error capturing httpclient KVs: #{e.message}"
|
35
|
+
Oboe.logger.debug e.backtrace.join('\n') if ::Oboe::Config[:verbose]
|
36
|
+
end
|
37
|
+
|
38
|
+
def do_request_with_oboe(method, uri, query, body, header, &block)
|
39
|
+
# If we're not tracing, just do a fast return.
|
40
|
+
if !Oboe.tracing?
|
41
|
+
return request_without_oboe(method, uri, query, body, header, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
begin
|
45
|
+
response_context = nil
|
46
|
+
|
47
|
+
# Avoid cross host tracing for blacklisted domains
|
48
|
+
blacklisted = Oboe::API.blacklisted?(uri.hostname)
|
49
|
+
|
50
|
+
kvs = oboe_collect(method, uri, query)
|
51
|
+
kvs['Blacklisted'] = true if blacklisted
|
52
|
+
|
53
|
+
Oboe::API.log_entry('httpclient', kvs)
|
54
|
+
kvs.clear
|
55
|
+
|
56
|
+
req_context = Oboe::Context.toString()
|
57
|
+
|
58
|
+
# Be aware of various ways to call/use httpclient
|
59
|
+
if header.is_a?(Array)
|
60
|
+
header.push ["X-Trace", req_context]
|
61
|
+
elsif header.is_a?(Hash)
|
62
|
+
header['X-Trace'] = req_context unless blacklisted
|
63
|
+
end
|
64
|
+
|
65
|
+
# The core httpclient call
|
66
|
+
response = do_request_without_oboe(method, uri, query, body, header, &block)
|
67
|
+
|
68
|
+
response_context = response.headers['X-Trace']
|
69
|
+
kvs['HTTPStatus'] = response.status_code
|
70
|
+
|
71
|
+
# If we get a redirect, report the location header
|
72
|
+
if ((300..308).to_a.include? response.status.to_i) && response.headers.key?("Location")
|
73
|
+
kvs["Location"] = response.headers["Location"]
|
74
|
+
end
|
75
|
+
|
76
|
+
if response_context && !blacklisted
|
77
|
+
Oboe::XTrace.continue_service_context(req_context, response_context)
|
78
|
+
end
|
79
|
+
|
80
|
+
response
|
81
|
+
rescue => e
|
82
|
+
Oboe::API.log_exception('httpclient', e)
|
83
|
+
raise e
|
84
|
+
ensure
|
85
|
+
Oboe::API.log_exit('httpclient', kvs)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def do_request_async_with_oboe(method, uri, query, body, header)
|
90
|
+
if Oboe.tracing?
|
91
|
+
# Since async is done by calling Thread.new { .. }, we somehow
|
92
|
+
# have to pass the tracing context into that new thread. Here
|
93
|
+
# we stowaway the context in the request headers to be picked up
|
94
|
+
# (and removed from req headers) in do_get_stream.
|
95
|
+
if header.is_a?(Array)
|
96
|
+
header.push ["oboe.context", Oboe::Context.toString]
|
97
|
+
elsif header.is_a?(Hash)
|
98
|
+
header['oboe.context'] = Oboe::Context.toString
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
do_request_async_without_oboe(method, uri, query, body, header)
|
103
|
+
end
|
104
|
+
|
105
|
+
def do_get_stream_with_oboe(req, proxy, conn)
|
106
|
+
unless req.headers.key?("oboe.context")
|
107
|
+
return do_get_stream_without_oboe(req, proxy, conn)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Pickup context and delete the headers stowaway
|
111
|
+
Oboe::Context.fromString req.headers["oboe.context"]
|
112
|
+
req.header.delete "oboe.context"
|
113
|
+
|
114
|
+
begin
|
115
|
+
response = nil
|
116
|
+
response_context = nil
|
117
|
+
uri = req.http_header.request_uri
|
118
|
+
method = req.http_header.request_method
|
119
|
+
|
120
|
+
# Avoid cross host tracing for blacklisted domains
|
121
|
+
blacklisted = Oboe::API.blacklisted?(uri.hostname)
|
122
|
+
|
123
|
+
kvs = oboe_collect(method, uri)
|
124
|
+
kvs['Blacklisted'] = true if blacklisted
|
125
|
+
kvs['Async'] = 1
|
126
|
+
|
127
|
+
Oboe::API.log_entry('httpclient', kvs)
|
128
|
+
kvs.clear
|
129
|
+
|
130
|
+
req_context = Oboe::Context.toString()
|
131
|
+
req.header.add('X-Trace', req_context)
|
132
|
+
|
133
|
+
# The core httpclient call
|
134
|
+
result = do_get_stream_without_oboe(req, proxy, conn)
|
135
|
+
|
136
|
+
# Older HTTPClient < 2.6.0 returns HTTPClient::Connection
|
137
|
+
if result.is_a?(::HTTP::Message)
|
138
|
+
response = result
|
139
|
+
else
|
140
|
+
response = conn.pop
|
141
|
+
end
|
142
|
+
|
143
|
+
response_context = response.headers['X-Trace']
|
144
|
+
kvs['HTTPStatus'] = response.status_code
|
145
|
+
|
146
|
+
# If we get a redirect, report the location header
|
147
|
+
if ((300..308).to_a.include? response.status.to_i) && response.headers.key?("Location")
|
148
|
+
kvs["Location"] = response.headers["Location"]
|
149
|
+
end
|
150
|
+
|
151
|
+
if response_context && !blacklisted
|
152
|
+
Oboe::XTrace.continue_service_context(req_context, response_context)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Older HTTPClient < 2.6.0 returns HTTPClient::Connection
|
156
|
+
conn.push response if result.is_a?(::HTTPClient::Connection)
|
157
|
+
result
|
158
|
+
rescue => e
|
159
|
+
Oboe::API.log_exception('httpclient', e)
|
160
|
+
raise e
|
161
|
+
ensure
|
162
|
+
# Oboe::API.log_exit('httpclient', kvs.merge('Async' => 1))
|
163
|
+
Oboe::API.log_exit('httpclient', kvs)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if Oboe::Config[:httpclient][:enabled] && defined?(::HTTPClient)
|
171
|
+
::Oboe.logger.info '[oboe/loading] Instrumenting httpclient' if Oboe::Config[:verbose]
|
172
|
+
::Oboe::Util.send_include(::HTTPClient, ::Oboe::Inst::HTTPClient)
|
173
|
+
end
|
data/lib/oboe/inst/rack.rb
CHANGED
@@ -19,7 +19,6 @@ module Oboe
|
|
19
19
|
report_kvs['Port'] = req.port
|
20
20
|
report_kvs['Proto'] = req.scheme
|
21
21
|
report_kvs['Query-String'] = URI.unescape(req.query_string) unless req.query_string.empty?
|
22
|
-
report_kvs[:URL] = URI.unescape(req.path)
|
23
22
|
report_kvs[:Method] = req.request_method
|
24
23
|
report_kvs['AJAX'] = true if req.xhr?
|
25
24
|
report_kvs['ClientIP'] = req.ip
|
@@ -62,9 +61,13 @@ module Oboe
|
|
62
61
|
end
|
63
62
|
|
64
63
|
req = ::Rack::Request.new(env)
|
65
|
-
|
66
64
|
report_kvs = {}
|
67
|
-
|
65
|
+
|
66
|
+
if Oboe::Config[:rack][:log_args]
|
67
|
+
report_kvs[:URL] = URI.unescape(req.fullpath)
|
68
|
+
else
|
69
|
+
report_kvs[:URL] = URI.unescape(req.path)
|
70
|
+
end
|
68
71
|
|
69
72
|
# Check for and validate X-Trace request header to pick up tracing context
|
70
73
|
xtrace = env.is_a?(Hash) ? env['HTTP_X_TRACE'] : nil
|
data/lib/oboe/inst/typhoeus.rb
CHANGED
@@ -28,15 +28,19 @@ module Oboe
|
|
28
28
|
end
|
29
29
|
|
30
30
|
kvs = {}
|
31
|
+
kvs['IsService'] = 1
|
31
32
|
kvs[:HTTPStatus] = response.code
|
32
33
|
kvs['Backtrace'] = Oboe::API.backtrace if Oboe::Config[:typhoeus][:collect_backtraces]
|
33
34
|
|
34
35
|
uri = URI(response.effective_url)
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
|
37
|
+
# Conditionally log query params
|
38
|
+
if Oboe::Config[:typhoeus][:log_args]
|
39
|
+
kvs['RemoteURL'] = uri.to_s
|
40
|
+
else
|
41
|
+
kvs['RemoteURL'] = uri.to_s.split('?').first
|
42
|
+
end
|
43
|
+
|
40
44
|
kvs['HTTPMethod'] = ::Oboe::Util.upcase(options[:method])
|
41
45
|
kvs['Blacklisted'] = true if blacklisted
|
42
46
|
|
data/lib/oboe/util.rb
CHANGED
@@ -138,6 +138,25 @@ module Oboe
|
|
138
138
|
end
|
139
139
|
end
|
140
140
|
|
141
|
+
|
142
|
+
##
|
143
|
+
# to_query
|
144
|
+
#
|
145
|
+
# Used under Ruby 1.8.7 to convert a hash into a URL
|
146
|
+
# query. A backport of Hash#to_query.
|
147
|
+
#
|
148
|
+
def to_query(h)
|
149
|
+
return "" unless h.is_a?(Hash)
|
150
|
+
|
151
|
+
# If called from a newer Ruby, use the builtin.
|
152
|
+
return h.to_query if RUBY_VERSION >= '1.9.3'
|
153
|
+
|
154
|
+
result = []
|
155
|
+
|
156
|
+
h.each { |k, v| result.push (k.to_s + '=' + v.to_s) }
|
157
|
+
return result.sort.join('&')
|
158
|
+
end
|
159
|
+
|
141
160
|
##
|
142
161
|
# build_report
|
143
162
|
#
|
@@ -174,6 +193,7 @@ module Oboe
|
|
174
193
|
platform_info['Ruby.Dalli.Version'] = "Dalli-#{::Dalli::VERSION}" if defined?(::Dalli)
|
175
194
|
platform_info['Ruby.Excon.Version'] = "Excon-#{::Excon::VERSION}" if defined?(::Excon::VERSION)
|
176
195
|
platform_info['Ruby.Faraday.Version'] = "Faraday-#{::Faraday::VERSION}" if defined?(::Faraday)
|
196
|
+
platform_info['Ruby.HTTPClient.Version'] = "HTTPClient-#{::HTTPClient::VERSION}" if defined?(::HTTPClient::VERSION)
|
177
197
|
platform_info['Ruby.MemCache.Version'] = "MemCache-#{::MemCache::VERSION}" if defined?(::MemCache)
|
178
198
|
platform_info['Ruby.Moped.Version'] = "Moped-#{::Moped::VERSION}" if defined?(::Moped)
|
179
199
|
platform_info['Ruby.Redis.Version'] = "Redis-#{::Redis::VERSION}" if defined?(::Redis)
|