elastic-transport 8.4.1 → 8.5.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/.github/workflows/license.yml +1 -1
- data/.github/workflows/otel.yml +2 -2
- data/.github/workflows/tests.yml +3 -3
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -1
- data/Gemfile-faraday1.gemfile +1 -1
- data/elastic-transport.gemspec +4 -1
- data/lib/elastic/transport/client.rb +27 -25
- data/lib/elastic/transport/opentelemetry.rb +3 -1
- data/lib/elastic/transport/transport/base.rb +33 -10
- data/lib/elastic/transport/transport/http/curb.rb +13 -7
- data/lib/elastic/transport/transport/http/faraday.rb +0 -1
- data/lib/elastic/transport/version.rb +1 -1
- data/spec/elastic/transport/base_spec.rb +1 -1
- data/spec/elastic/transport/client_spec.rb +2 -3
- data/spec/elastic/transport/opentelemetry_spec.rb +41 -27
- data/spec/spec_helper.rb +0 -1
- data/test/unit/adapters_test.rb +81 -71
- data/test/unit/connection_test.rb +5 -5
- data/test/unit/transport_curb_test.rb +117 -103
- data/test/unit/transport_faraday_test.rb +228 -205
- data/test/unit/transport_manticore_test.rb +72 -61
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5f325dbed521a79ebb43a9b74fdce73bc7184717c9ec6939262f227faeb2adc4
|
|
4
|
+
data.tar.gz: 193b1b6a263e079c987ab3ad59f5842c8872bb956c7dd16dc751560dc3c21fac
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: bb05fa43519780d747d3640687fcd3c600e3510c54e41eaf3dc4ceeadc05ba6c794f051a301fd5fd2a55ef3a157ce8fdb2098a63d5c28ed14d73d6cbe0432252
|
|
7
|
+
data.tar.gz: cc35d78faa229b78ee06eaf3d341dac37211f7683cf9f30db19bf57f4228071469cc3fddaac76a99ad749fb2690b015d03a3bebf0fb3fd976d66f7f437cdc0c2
|
data/.github/workflows/otel.yml
CHANGED
data/.github/workflows/tests.yml
CHANGED
|
@@ -16,8 +16,8 @@ jobs:
|
|
|
16
16
|
strategy:
|
|
17
17
|
fail-fast: false
|
|
18
18
|
matrix:
|
|
19
|
-
ruby: ['3.2', '3.3', '3.4', 'jruby-9.3', 'jruby-9.4', 'jruby-10.0']
|
|
20
|
-
es_version: ['8.
|
|
19
|
+
ruby: ['3.2', '3.3', '3.4', '4.0', 'jruby-9.3', 'jruby-9.4', 'jruby-10.0']
|
|
20
|
+
es_version: ['8.19.14-SNAPSHOT', '9.2.8-SNAPSHOT', '9.3.3-SNAPSHOT', '9.4.0-SNAPSHOT']
|
|
21
21
|
runs-on: ubuntu-latest
|
|
22
22
|
steps:
|
|
23
23
|
- uses: actions/checkout@v4
|
|
@@ -55,7 +55,7 @@ jobs:
|
|
|
55
55
|
fail-fast: false
|
|
56
56
|
matrix:
|
|
57
57
|
ruby: ['3.0', '3.1', '3.2', '3.3', 'jruby-9.3']
|
|
58
|
-
es_version: ['8.19.
|
|
58
|
+
es_version: ['8.19.14-SNAPSHOT']
|
|
59
59
|
runs-on: ubuntu-latest
|
|
60
60
|
steps:
|
|
61
61
|
- uses: actions/checkout@v4
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## 8.5.0
|
|
2
|
+
|
|
3
|
+
* OpenTelemetry:
|
|
4
|
+
* Updates OpenTelemetry conventions
|
|
5
|
+
* Updates code to capture `error.type` and `status_code` in OpenTelemetry.
|
|
6
|
+
* Captures ES|QL queries as SEARCH endpoints.
|
|
7
|
+
* Tested Ruby versions for elastic-transport `8.5.0`:
|
|
8
|
+
* MRI: `3.2`, `3.3`, `3.4`, `4.0`.
|
|
9
|
+
* JRuby: `9.3`, `9.4`, `10.0`.
|
|
10
|
+
|
|
1
11
|
## 8.4.1
|
|
2
12
|
|
|
3
13
|
- Moves `require 'timeout'` to the classes that use it. Closed [#79](https://github.com/elastic/elastic-transport-ruby/issues/79).
|
data/Gemfile
CHANGED
data/Gemfile-faraday1.gemfile
CHANGED
data/elastic-transport.gemspec
CHANGED
|
@@ -48,7 +48,10 @@ Gem::Specification.new do |s|
|
|
|
48
48
|
s.add_dependency 'multi_json'
|
|
49
49
|
|
|
50
50
|
# Faraday Adapters
|
|
51
|
-
|
|
51
|
+
if defined? JRUBY_VERSION
|
|
52
|
+
s.add_development_dependency 'manticore'
|
|
53
|
+
s.add_development_dependency 'base64'
|
|
54
|
+
end
|
|
52
55
|
s.add_development_dependency 'curb' unless defined? JRUBY_VERSION
|
|
53
56
|
s.add_development_dependency 'bundler'
|
|
54
57
|
s.add_development_dependency 'cane'
|
|
@@ -174,18 +174,19 @@ module Elastic
|
|
|
174
174
|
span_name = opts[:endpoint] || method
|
|
175
175
|
@otel.tracer.in_span(span_name) do |span|
|
|
176
176
|
span['http.request.method'] = method
|
|
177
|
-
span['db.system'] = 'elasticsearch'
|
|
177
|
+
span['db.system.name'] = 'elasticsearch'.freeze
|
|
178
|
+
span['kind'] = 'CLIENT'.freeze
|
|
178
179
|
opts[:defined_params]&.each do |k, v|
|
|
179
|
-
if v.respond_to?(:join)
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
span["db.operation.parameter.#{k}"] = if v.respond_to?(:join)
|
|
181
|
+
v.join(',')
|
|
182
|
+
else
|
|
183
|
+
v
|
|
184
|
+
end
|
|
184
185
|
end
|
|
185
|
-
if body_as_json = @otel.process_body(body, opts[:endpoint])
|
|
186
|
-
span['db.
|
|
186
|
+
if (body_as_json = @otel.process_body(body, opts[:endpoint]))
|
|
187
|
+
span['db.query.text'] = body_as_json
|
|
187
188
|
end
|
|
188
|
-
span['db.operation'] = opts[:endpoint] if opts[:endpoint]
|
|
189
|
+
span['db.operation.name'] = opts[:endpoint] if opts[:endpoint]
|
|
189
190
|
transport.perform_request(method, path, params || {}, body, headers)
|
|
190
191
|
end
|
|
191
192
|
else
|
|
@@ -271,27 +272,28 @@ module Elastic
|
|
|
271
272
|
# Construct a new `URI::Generic` directly from the array returned by URI::split.
|
|
272
273
|
# This avoids `URI::HTTP` and `URI::HTTPS`, which supply default ports.
|
|
273
274
|
uri = URI::Generic.new(*URI.split(host))
|
|
274
|
-
|
|
275
275
|
default_port = uri.scheme == 'https' ? 443 : DEFAULT_PORT
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
:
|
|
279
|
-
:
|
|
280
|
-
:
|
|
281
|
-
:
|
|
282
|
-
:
|
|
276
|
+
{
|
|
277
|
+
scheme: uri.scheme,
|
|
278
|
+
user: uri.user,
|
|
279
|
+
password: uri.password,
|
|
280
|
+
host: uri.host,
|
|
281
|
+
path: uri.path,
|
|
282
|
+
port: uri.port || default_port
|
|
283
|
+
}
|
|
283
284
|
else
|
|
284
285
|
host, port = host.split(':')
|
|
285
|
-
{ :host
|
|
286
|
-
:port => port }
|
|
286
|
+
{ host: host, port: port }
|
|
287
287
|
end
|
|
288
288
|
when URI
|
|
289
|
-
{
|
|
290
|
-
:
|
|
291
|
-
:
|
|
292
|
-
:
|
|
293
|
-
:
|
|
294
|
-
:
|
|
289
|
+
{
|
|
290
|
+
scheme: host.scheme,
|
|
291
|
+
user: host.user,
|
|
292
|
+
password: host.password,
|
|
293
|
+
host: host.host,
|
|
294
|
+
path: host.path,
|
|
295
|
+
port: host.port
|
|
296
|
+
}
|
|
295
297
|
when Hash
|
|
296
298
|
host
|
|
297
299
|
else
|
|
@@ -42,10 +42,12 @@ module Elastic
|
|
|
42
42
|
'async_search.submit',
|
|
43
43
|
'msearch',
|
|
44
44
|
'eql.search',
|
|
45
|
+
'esql.async_query',
|
|
46
|
+
'esql.query',
|
|
45
47
|
'terms_enum',
|
|
46
48
|
'search_template',
|
|
47
49
|
'msearch_template',
|
|
48
|
-
'render_search_template'
|
|
50
|
+
'render_search_template'
|
|
49
51
|
]
|
|
50
52
|
|
|
51
53
|
# Initialize the Open Telemetry wrapper object. Takes the options originally passed to
|
|
@@ -225,15 +225,17 @@ module Elastic
|
|
|
225
225
|
#
|
|
226
226
|
def __raise_transport_error(response)
|
|
227
227
|
error = ERRORS[response.status] || ServerError
|
|
228
|
-
|
|
228
|
+
message = "[#{response.status}] #{response.body}"
|
|
229
|
+
capture_otel_error_attributes(message)
|
|
230
|
+
raise error.new message
|
|
229
231
|
end
|
|
230
232
|
|
|
231
233
|
# Converts any non-String object to JSON
|
|
232
234
|
#
|
|
233
235
|
# @api private
|
|
234
236
|
#
|
|
235
|
-
def __convert_to_json(
|
|
236
|
-
|
|
237
|
+
def __convert_to_json(obj = nil, options = {})
|
|
238
|
+
obj.is_a?(String) ? obj : serializer.dump(obj, options)
|
|
237
239
|
end
|
|
238
240
|
|
|
239
241
|
# Returns a full URL based on information from host
|
|
@@ -275,9 +277,7 @@ module Elastic
|
|
|
275
277
|
tries = 0
|
|
276
278
|
reload_on_failure = opts.fetch(:reload_on_failure, @options[:reload_on_failure])
|
|
277
279
|
delay_on_retry = opts.fetch(:delay_on_retry, @options[:delay_on_retry])
|
|
278
|
-
|
|
279
280
|
max_retries = max_retries(opts) || max_retries(options)
|
|
280
|
-
|
|
281
281
|
params = params.clone
|
|
282
282
|
# Transforms ignore status codes to Integer
|
|
283
283
|
ignore = Array(params.delete(:ignore)).compact.map(&:to_i)
|
|
@@ -306,7 +306,9 @@ module Elastic
|
|
|
306
306
|
if tries <= (max_retries || DEFAULT_MAX_RETRIES)
|
|
307
307
|
retry
|
|
308
308
|
else
|
|
309
|
-
|
|
309
|
+
message = "[#{e.class}] Cannot get response from #{url} after #{tries} tries"
|
|
310
|
+
log_fatal(message)
|
|
311
|
+
capture_otel_error_attributes(message)
|
|
310
312
|
raise e
|
|
311
313
|
end
|
|
312
314
|
rescue *host_unreachable_exceptions => e
|
|
@@ -321,17 +323,24 @@ module Elastic
|
|
|
321
323
|
|
|
322
324
|
exception = Elastic::Transport::Transport::Error.new(e.message)
|
|
323
325
|
|
|
324
|
-
|
|
326
|
+
unless max_retries
|
|
327
|
+
capture_otel_error_attributes(exception.message)
|
|
328
|
+
raise exception
|
|
329
|
+
end
|
|
325
330
|
|
|
326
331
|
log_warn "[#{e.class}] Attempt #{tries} connecting to #{connection.host.inspect}"
|
|
327
332
|
if tries <= max_retries
|
|
328
333
|
retry
|
|
329
334
|
else
|
|
330
|
-
|
|
335
|
+
message = "[#{e.class}] Cannot connect to #{connection.host.inspect} after #{tries} tries"
|
|
336
|
+
log_fatal(message)
|
|
337
|
+
capture_otel_error_attributes(message)
|
|
331
338
|
raise exception
|
|
332
339
|
end
|
|
333
340
|
rescue Exception => e
|
|
334
|
-
|
|
341
|
+
message = "[#{e.class}] #{e.message} (#{connection.host.inspect if connection})"
|
|
342
|
+
log_fatal message
|
|
343
|
+
capture_otel_error_attributes(message)
|
|
335
344
|
raise e
|
|
336
345
|
end #/begin
|
|
337
346
|
|
|
@@ -362,6 +371,10 @@ module Elastic
|
|
|
362
371
|
__trace(method, path, params, connection_headers(connection), body, url, response, nil, 'N/A', duration) if tracer
|
|
363
372
|
log_warn(response.headers['warning']) if response.headers&.[]('warning')
|
|
364
373
|
|
|
374
|
+
if opentelemetry?
|
|
375
|
+
::OpenTelemetry::Trace.current_span&.set_attribute('db.response.status_code', response.status)
|
|
376
|
+
end
|
|
377
|
+
|
|
365
378
|
Response.new response.status, json || response.body, response.headers
|
|
366
379
|
ensure
|
|
367
380
|
@last_request_at = Time.now
|
|
@@ -476,13 +489,23 @@ module Elastic
|
|
|
476
489
|
url.to_s.gsub(/\/\/(.+):(.+)@/, '//' + '\1:' + SANITIZED_PASSWORD + '@')
|
|
477
490
|
end
|
|
478
491
|
|
|
492
|
+
def opentelemetry?
|
|
493
|
+
defined?(::OpenTelemetry)
|
|
494
|
+
end
|
|
495
|
+
|
|
479
496
|
def capture_otel_span_attributes(connection, url)
|
|
480
|
-
if
|
|
497
|
+
if opentelemetry?
|
|
481
498
|
::OpenTelemetry::Trace.current_span&.set_attribute('url.full', sanitize_url(url))
|
|
482
499
|
::OpenTelemetry::Trace.current_span&.set_attribute('server.address', connection.host[:host])
|
|
483
500
|
::OpenTelemetry::Trace.current_span&.set_attribute('server.port', connection.host[:port].to_i)
|
|
484
501
|
end
|
|
485
502
|
end
|
|
503
|
+
|
|
504
|
+
def capture_otel_error_attributes(error)
|
|
505
|
+
if opentelemetry?
|
|
506
|
+
::OpenTelemetry::Trace.current_span&.set_attribute('error.type', error)
|
|
507
|
+
end
|
|
508
|
+
end
|
|
486
509
|
end
|
|
487
510
|
end
|
|
488
511
|
end
|
|
@@ -44,13 +44,7 @@ module Elastic
|
|
|
44
44
|
connection.connection.set :nobody, false
|
|
45
45
|
connection.connection.put_data = body if body
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
if connection.connection.headers
|
|
49
|
-
connection.connection.headers.merge!(headers)
|
|
50
|
-
else
|
|
51
|
-
connection.connection.headers = headers
|
|
52
|
-
end
|
|
53
|
-
end
|
|
47
|
+
parse_headers!(headers, connection)
|
|
54
48
|
else raise ArgumentError, "Unsupported HTTP method: #{method}"
|
|
55
49
|
end
|
|
56
50
|
|
|
@@ -68,6 +62,18 @@ module Elastic
|
|
|
68
62
|
end
|
|
69
63
|
end
|
|
70
64
|
|
|
65
|
+
# Merges headers already present in the connection and the ones passed in to perform_request
|
|
66
|
+
#
|
|
67
|
+
def parse_headers!(headers, connection)
|
|
68
|
+
return unless headers
|
|
69
|
+
|
|
70
|
+
if connection.connection.headers
|
|
71
|
+
connection.connection.headers.merge!(headers)
|
|
72
|
+
else
|
|
73
|
+
connection.connection.headers = headers
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
71
77
|
# Builds and returns a connection
|
|
72
78
|
#
|
|
73
79
|
# @return [Connections::Connection]
|
|
@@ -40,7 +40,6 @@ module Elastic
|
|
|
40
40
|
body, headers = compress_request(body, headers)
|
|
41
41
|
|
|
42
42
|
response = connection.connection.run_request(method.downcase.to_sym, url, body, headers)
|
|
43
|
-
|
|
44
43
|
Response.new(response.status, decompress_response(response.body), response.headers)
|
|
45
44
|
end
|
|
46
45
|
end
|
|
@@ -137,7 +137,7 @@ describe Elastic::Transport::Transport::Base do
|
|
|
137
137
|
|
|
138
138
|
it 'retries on 404 status the specified number of max_retries' do
|
|
139
139
|
expect do
|
|
140
|
-
client.transport.perform_request('GET', 'myindex/_doc/
|
|
140
|
+
client.transport.perform_request('GET', 'myindex/_doc/42?routing=FOOBARBAZ', {}, nil, nil, retry_on_failure: 5)
|
|
141
141
|
end.to raise_exception(Elastic::Transport::Transport::Errors::NotFound)
|
|
142
142
|
end
|
|
143
143
|
end
|
|
@@ -134,7 +134,6 @@ describe Elastic::Transport::Client do
|
|
|
134
134
|
end
|
|
135
135
|
|
|
136
136
|
context 'when a User-Agent header is specified as a client option' do
|
|
137
|
-
|
|
138
137
|
let(:client) do
|
|
139
138
|
described_class.new(transport_class: Elastic::Transport::Transport::HTTP::Curb,
|
|
140
139
|
transport_options: { headers: { 'User-Agent' => 'testing' } })
|
|
@@ -1619,7 +1618,7 @@ describe Elastic::Transport::Client do
|
|
|
1619
1618
|
context 'when an invalid url is specified' do
|
|
1620
1619
|
it 'raises an exception' do
|
|
1621
1620
|
expect {
|
|
1622
|
-
client.perform_request('GET', 'myindex/_doc/
|
|
1621
|
+
client.perform_request('GET', 'myindex/_doc/42?routing=FOOBARBAZ')
|
|
1623
1622
|
}.to raise_exception(Elastic::Transport::Transport::Errors::NotFound)
|
|
1624
1623
|
end
|
|
1625
1624
|
end
|
|
@@ -1730,7 +1729,7 @@ describe Elastic::Transport::Client do
|
|
|
1730
1729
|
client.transport.reload_connections!
|
|
1731
1730
|
response = client.perform_request('GET', '_nodes/stats/http')
|
|
1732
1731
|
connections_after = response.body['nodes'].values.find { |n| n['name'] == node_names.first }['http']['total_opened']
|
|
1733
|
-
expect(connections_after).to be >=
|
|
1732
|
+
expect(connections_after).to be >= connections_before
|
|
1734
1733
|
end
|
|
1735
1734
|
end
|
|
1736
1735
|
end
|
|
@@ -65,32 +65,36 @@ if defined?(::OpenTelemetry)
|
|
|
65
65
|
|
|
66
66
|
span = exporter.finished_spans.find { |s| s.name == 'create' }
|
|
67
67
|
expect(span.name).to eql('create')
|
|
68
|
-
expect(span.attributes['db.system']).to eql('elasticsearch')
|
|
69
|
-
expect(span.attributes['db.
|
|
70
|
-
expect(span.attributes['db.
|
|
71
|
-
expect(span.attributes['db.operation']).to eq('create')
|
|
68
|
+
expect(span.attributes['db.system.name']).to eql('elasticsearch')
|
|
69
|
+
expect(span.attributes['db.operation.parameter.index']).to eql('users')
|
|
70
|
+
expect(span.attributes['db.operation.parameter.id']).to eq('abc')
|
|
71
|
+
expect(span.attributes['db.operation.name']).to eq('create')
|
|
72
72
|
expect(span.attributes['db.statement']).to be_nil
|
|
73
73
|
expect(span.attributes['http.request.method']).to eq('POST')
|
|
74
74
|
expect(span.attributes['server.address']).to eq('localhost')
|
|
75
75
|
expect(span.attributes['server.port']).to eq(TEST_PORT.to_i)
|
|
76
|
+
expect(span.attributes['kind']).to eq('CLIENT')
|
|
77
|
+
expect(span.attributes['db.response.status_code']).to eq(201)
|
|
76
78
|
end
|
|
77
79
|
|
|
78
80
|
context 'with list a path parameter' do
|
|
79
81
|
it 'creates a span with path parameters' do
|
|
80
82
|
client.perform_request(
|
|
81
83
|
'GET', '_cluster/state/foo,bar', {}, nil, {},
|
|
82
|
-
{ defined_params: { metric: ['foo', 'bar']}, endpoint: 'cluster.state' }
|
|
84
|
+
{ defined_params: { metric: ['foo', 'bar'] }, endpoint: 'cluster.state' }
|
|
83
85
|
)
|
|
84
86
|
|
|
85
87
|
span = exporter.finished_spans.find { |s| s.name == 'cluster.state' }
|
|
86
88
|
expect(span.name).to eql('cluster.state')
|
|
87
|
-
expect(span.attributes['db.system']).to eql('elasticsearch')
|
|
88
|
-
expect(span.attributes['db.
|
|
89
|
-
expect(span.attributes['db.operation']).to eq('cluster.state')
|
|
90
|
-
expect(span.attributes['db.
|
|
89
|
+
expect(span.attributes['db.system.name']).to eql('elasticsearch')
|
|
90
|
+
expect(span.attributes['db.operation.parameter.metric']).to eql('foo,bar')
|
|
91
|
+
expect(span.attributes['db.operation.name']).to eq('cluster.state')
|
|
92
|
+
expect(span.attributes['db.query.text']).to be_nil
|
|
91
93
|
expect(span.attributes['http.request.method']).to eq('GET')
|
|
92
94
|
expect(span.attributes['server.address']).to eq('localhost')
|
|
93
95
|
expect(span.attributes['server.port']).to eq(TEST_PORT.to_i)
|
|
96
|
+
expect(span.attributes['kind']).to eq('CLIENT')
|
|
97
|
+
expect(span.attributes['db.response.status_code']).to eq(200)
|
|
94
98
|
end
|
|
95
99
|
end
|
|
96
100
|
end
|
|
@@ -100,13 +104,13 @@ if defined?(::OpenTelemetry)
|
|
|
100
104
|
{ query: { match: { password: { query: 'secret' } } } }
|
|
101
105
|
end
|
|
102
106
|
|
|
103
|
-
it 'creates a span and omits db.
|
|
107
|
+
it 'creates a span and omits db.query.text' do
|
|
104
108
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
105
109
|
|
|
106
110
|
expect(span.name).to eql('search')
|
|
107
|
-
expect(span.attributes['db.system']).to eql('elasticsearch')
|
|
108
|
-
expect(span.attributes['db.operation']).to eq('search')
|
|
109
|
-
expect(span.attributes['db.
|
|
111
|
+
expect(span.attributes['db.system.name']).to eql('elasticsearch')
|
|
112
|
+
expect(span.attributes['db.operation.name']).to eq('search')
|
|
113
|
+
expect(span.attributes['db.query.text']).to be_nil
|
|
110
114
|
expect(span.attributes['http.request.method']).to eq('GET')
|
|
111
115
|
expect(span.attributes['server.address']).to eq('localhost')
|
|
112
116
|
expect(span.attributes['server.port']).to eq(TEST_PORT.to_i)
|
|
@@ -128,7 +132,7 @@ if defined?(::OpenTelemetry)
|
|
|
128
132
|
it 'sanitizes the body' do
|
|
129
133
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
130
134
|
|
|
131
|
-
expect(span.attributes['db.
|
|
135
|
+
expect(span.attributes['db.query.text']).to eq(sanitized_body.to_json)
|
|
132
136
|
end
|
|
133
137
|
end
|
|
134
138
|
|
|
@@ -147,13 +151,13 @@ if defined?(::OpenTelemetry)
|
|
|
147
151
|
it 'sanitizes the body' do
|
|
148
152
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
149
153
|
|
|
150
|
-
expect(span.attributes['db.
|
|
154
|
+
expect(span.attributes['db.query.text']).to eq(sanitized_body.to_json)
|
|
151
155
|
end
|
|
152
156
|
end
|
|
153
157
|
|
|
154
158
|
context 'with custom keys' do
|
|
155
159
|
let(:body) do
|
|
156
|
-
{ query: { match: { sensitive: { query: 'secret'} } } }
|
|
160
|
+
{ query: { match: { sensitive: { query: 'secret' } } } }
|
|
157
161
|
end
|
|
158
162
|
|
|
159
163
|
let(:sanitized_body) do
|
|
@@ -176,7 +180,7 @@ if defined?(::OpenTelemetry)
|
|
|
176
180
|
it 'sanitizes the body' do
|
|
177
181
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
178
182
|
|
|
179
|
-
expect(span.attributes['db.
|
|
183
|
+
expect(span.attributes['db.query.text']).to eq(sanitized_body.to_json)
|
|
180
184
|
end
|
|
181
185
|
end
|
|
182
186
|
end
|
|
@@ -196,14 +200,14 @@ if defined?(::OpenTelemetry)
|
|
|
196
200
|
context 'when the body is a string' do
|
|
197
201
|
it 'includes the raw body' do
|
|
198
202
|
client.perform_request('GET', '/_search', nil, body.to_json, nil, endpoint: 'search')
|
|
199
|
-
expect(span.attributes['db.
|
|
203
|
+
expect(span.attributes['db.query.text']).to eq(body.to_json)
|
|
200
204
|
end
|
|
201
205
|
end
|
|
202
206
|
|
|
203
207
|
context' when the body is a hash' do
|
|
204
208
|
it 'includes the raw body' do
|
|
205
209
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
206
|
-
expect(span.attributes['db.
|
|
210
|
+
expect(span.attributes['db.query.text']).to eq(body.to_json)
|
|
207
211
|
end
|
|
208
212
|
end
|
|
209
213
|
end
|
|
@@ -222,7 +226,7 @@ if defined?(::OpenTelemetry)
|
|
|
222
226
|
|
|
223
227
|
it 'does not include anything' do
|
|
224
228
|
client.perform_request('GET', '/_search', nil, body, nil, endpoint: 'search')
|
|
225
|
-
expect(span.attributes['db.
|
|
229
|
+
expect(span.attributes['db.query.text']).to be_nil
|
|
226
230
|
end
|
|
227
231
|
end
|
|
228
232
|
|
|
@@ -231,12 +235,12 @@ if defined?(::OpenTelemetry)
|
|
|
231
235
|
{ query: { match: { something: "test" } } }
|
|
232
236
|
end
|
|
233
237
|
|
|
234
|
-
it 'does not capture db.
|
|
238
|
+
it 'does not capture db.query.text' do
|
|
235
239
|
client.perform_request(
|
|
236
240
|
'POST', '_all/_delete_by_query', nil, body, nil, endpoint: 'delete_by_query'
|
|
237
241
|
)
|
|
238
242
|
|
|
239
|
-
expect(span.attributes['db.
|
|
243
|
+
expect(span.attributes['db.query.text']).to be_nil
|
|
240
244
|
end
|
|
241
245
|
end
|
|
242
246
|
|
|
@@ -248,10 +252,10 @@ if defined?(::OpenTelemetry)
|
|
|
248
252
|
|
|
249
253
|
span = exporter.finished_spans.find { |s| s.name == 'GET' }
|
|
250
254
|
expect(span.name).to eql('GET')
|
|
251
|
-
expect(span.attributes['db.system']).to eql('elasticsearch')
|
|
252
|
-
expect(span.attributes['db.
|
|
255
|
+
expect(span.attributes['db.system.name']).to eql('elasticsearch')
|
|
256
|
+
expect(span.attributes['db.operation.parameter']).to be_nil
|
|
253
257
|
expect(span.attributes['db.operation']).to be_nil
|
|
254
|
-
expect(span.attributes['db.
|
|
258
|
+
expect(span.attributes['db.query.text']).to be_nil
|
|
255
259
|
expect(span.attributes['http.request.method']).to eq('GET')
|
|
256
260
|
expect(span.attributes['server.address']).to eq('localhost')
|
|
257
261
|
expect(span.attributes['server.port']).to eq(TEST_PORT.to_i)
|
|
@@ -259,6 +263,16 @@ if defined?(::OpenTelemetry)
|
|
|
259
263
|
end
|
|
260
264
|
end
|
|
261
265
|
|
|
266
|
+
context 'when there is an error' do
|
|
267
|
+
it 'it sets error.type' do
|
|
268
|
+
expect do
|
|
269
|
+
client.perform_request('GET', '/_wrongendpoint', nil, nil, nil, endpoint: 'wrong')
|
|
270
|
+
end.to raise_error
|
|
271
|
+
|
|
272
|
+
expect(span.attributes['error.type']).to match(/error/)
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
262
276
|
context 'when the ENV variable OTEL_RUBY_INSTRUMENTATION_ELASTICSEARCH_ENABLED is set' do
|
|
263
277
|
context 'to true' do
|
|
264
278
|
around do |ex|
|
|
@@ -324,7 +338,7 @@ if defined?(::OpenTelemetry)
|
|
|
324
338
|
|
|
325
339
|
context 'sanitize in URL' do
|
|
326
340
|
let(:client) {
|
|
327
|
-
Elastic::Transport::Client.new(host:
|
|
341
|
+
Elastic::Transport::Client.new(host: "http://elastic:changeme@#{ELASTICSEARCH_HOSTS.first}")
|
|
328
342
|
}
|
|
329
343
|
|
|
330
344
|
it 'sanitizes URL' do
|
|
@@ -334,7 +348,7 @@ if defined?(::OpenTelemetry)
|
|
|
334
348
|
|
|
335
349
|
span = exporter.finished_spans.find { |s| s.name == 'GET' }
|
|
336
350
|
expect(span.name).to eql('GET')
|
|
337
|
-
expect(span.attributes['url.full']).to match(/http:\/\/elastic:\*+@localhost
|
|
351
|
+
expect(span.attributes['url.full']).to match(/http:\/\/elastic:\*+@localhost:/)
|
|
338
352
|
end
|
|
339
353
|
end
|
|
340
354
|
end
|