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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 11e535361d6ddf6ec6a8dca58b742b50f42ba114
4
- data.tar.gz: ef8bc3bc820153012eba2de3fdbd3eb66c36f90c
3
+ metadata.gz: f5af7c88e442b978109bfd9e26216d22ba96ebbc
4
+ data.tar.gz: 87967943c1a3c45db5e9576a9dd629eb4207254c
5
5
  SHA512:
6
- metadata.gz: 0c7b74535912fea2bb7e7a431b1c8e6800fb042f46b43201ee39e8abd202944783cb4a8cd0edf70bb17d578959a4f6e51b214528071306946def97ef771e0d8e
7
- data.tar.gz: dde645f8bdc7320d53cfabe2b2fda1deb2dacd5d107f4e81017e688a2402b4f065b1a63823c555ef29d1e8114a10b1744f040087bc301b595d05c2eda127282c
6
+ metadata.gz: f534a642ed23073afa600719331797cfe7981d007918d18b172776e0a31783e260dc288bc3d7d8b507abae3abc51356f6581aa170af0cfa763bef5190fae9f8a
7
+ data.tar.gz: 2babaaa796835cc02dade64dd032ce6f154dbb491e25c54b7f34da1acaf604a06ccf9bac8a27eb8fa6ea0b97daf17999000ebf494e15046ae18c4c377e76f116
@@ -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'
@@ -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
- if key == :sample_rate
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
- unless @@config.key?(sym)
181
- Oboe.logger.warn "[oboe/warn] Unknown method call on Oboe::Config: #{sym}"
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
@@ -15,7 +15,8 @@ module Oboe
15
15
  kvs['RemoteProtocol'] = ::Oboe::Util.upcase(@data[:scheme])
16
16
  kvs['RemoteHost'] = @data[:host]
17
17
 
18
- if @data[:query] && @data[:query].length
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]
@@ -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
- opts['ServiceArg'] = req.path
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
@@ -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
- report_kvs[:URL] = URI.unescape(req.path)
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
@@ -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
- kvs['IsService'] = 1
36
- kvs['RemoteProtocol'] = ::Oboe::Util.upcase(uri.scheme)
37
- kvs['RemoteHost'] = uri.host
38
- kvs['RemotePort'] = uri.port ? uri.port : 80
39
- kvs['ServiceArg'] = uri.path
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
 
@@ -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)