logstash-output-scalyr 0.2.6 → 0.2.8.beta

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.
@@ -1,85 +0,0 @@
1
- require 'benchmark'
2
- require 'json'
3
- require 'jrjackson'
4
-
5
- require_relative '../../lib/scalyr/common/util'
6
- require_relative './util'
7
-
8
- ITERATIONS = 500
9
-
10
- def json_serialize_data_native(data)
11
- data.to_json
12
- end
13
-
14
- def json_serialize_data_jrjackson(data)
15
- JrJackson::Json.dump(data)
16
- end
17
-
18
- DATASETS = {
19
- :keys_50 => generate_data_array_for_spec([3, 3, 3, 2]),
20
- :keys_200 => generate_data_array_for_spec([4, 4, 3, 4]),
21
- :keys_200_flat => generate_data_array_for_spec([200]),
22
- :keys_512 => generate_data_array_for_spec([8, 4, 4, 4]),
23
- :keys_960 => generate_data_array_for_spec([12, 5, 4, 4]),
24
- :keys_2700 => generate_data_array_for_spec([14, 8, 6, 4])
25
- }
26
-
27
- def run_benchmark_and_print_results(data, run_benchmark_func)
28
- puts ""
29
- puts "Using %s total keys in a hash" % [Scalyr::Common::Util.flatten(data[0]).count]
30
- puts ""
31
-
32
- result = []
33
- ITERATIONS.times do |i|
34
- result << Benchmark.measure { run_benchmark_func.(data[i]) }
35
- end
36
-
37
- sum = result.inject(nil) { |sum, t| sum.nil? ? sum = t : sum += t }
38
- avg = sum / result.size
39
-
40
- Benchmark.bm(7, "sum:", "avg:") do |b|
41
- [sum, avg]
42
- end
43
- puts ""
44
- end
45
-
46
- puts "Using %s iterations" % [ITERATIONS]
47
- puts ""
48
-
49
- puts "native"
50
- puts "==============================="
51
-
52
- # Around ~50 keys in a hash
53
- data = DATASETS[:keys_50]
54
- run_benchmark_and_print_results(data, method(:json_serialize_data_native))
55
-
56
- # Around ~200 keys in a hash
57
- data = DATASETS[:keys_200]
58
- run_benchmark_and_print_results(data, method(:json_serialize_data_native))
59
-
60
- # Around ~200 keys in a hash (single level)
61
- data = DATASETS[:keys_200_flat]
62
- run_benchmark_and_print_results(data, method(:json_serialize_data_native))
63
-
64
- # Around ~2700 keys in a hash
65
- data = DATASETS[:keys_2700]
66
- run_benchmark_and_print_results(data, method(:json_serialize_data_native))
67
-
68
- puts "jrjackson"
69
- puts "==============================="
70
-
71
- # Around ~50 keys in a hash
72
- data = DATASETS[:keys_50]
73
- run_benchmark_and_print_results(data, method(:json_serialize_data_jrjackson))
74
-
75
- # Around ~200 keys in a hash
76
- data = DATASETS[:keys_200]
77
- run_benchmark_and_print_results(data, method(:json_serialize_data_jrjackson))
78
-
79
- # Around ~200 keys in a hash (single level)
80
- data = DATASETS[:keys_200_flat]
81
- run_benchmark_and_print_results(data, method(:json_serialize_data_jrjackson))
82
-
83
- # Around ~2700 keys in a hash
84
- data = DATASETS[:keys_2700]
85
- run_benchmark_and_print_results(data, method(:json_serialize_data_jrjackson))
@@ -1,48 +0,0 @@
1
- require 'benchmark'
2
- require 'quantile'
3
-
4
- require_relative '../../lib/scalyr/common/util'
5
-
6
- # Micro benchmark which measures how much overhead Quantile.observe adds vs random sampling to see
7
- # where making sampling (e.g. on event level metrics) is desired
8
-
9
- ITERATIONS = 10000
10
-
11
- def run_benchmark_and_print_results(run_benchmark_func)
12
- result = []
13
- ITERATIONS.times do |i|
14
- result << Benchmark.measure { run_benchmark_func.() }
15
- end
16
-
17
- sum = result.inject(nil) { |sum, t| sum.nil? ? sum = t : sum += t }
18
- avg = sum / result.size
19
-
20
- Benchmark.bm(7, "sum:", "avg:") do |b|
21
- [sum, avg]
22
- end
23
- puts ""
24
- end
25
-
26
-
27
- puts "Using %s iterations" % [ITERATIONS]
28
- puts ""
29
-
30
- @value = Quantile::Estimator.new
31
- @prng = Random.new
32
-
33
- def quantile_observe()
34
- @value.observe(5)
35
- end
36
-
37
- def random_sample()
38
- return @prng.rand(0.0..1.0) < 0.5
39
- end
40
-
41
- puts "Quartile.observe()"
42
- puts "==============================="
43
-
44
- run_benchmark_and_print_results(method(:quantile_observe))
45
-
46
- puts "random sample"
47
- puts "==============================="
48
- run_benchmark_and_print_results(method(:random_sample))
@@ -1,107 +0,0 @@
1
- require 'benchmark'
2
- require 'quantile'
3
-
4
- require_relative '../../lib/scalyr/constants'
5
- require_relative '../../lib/scalyr/common/util'
6
- require_relative './util'
7
-
8
- # Micro benchmark which measures how long "set_session_level_serverhost_on_events" takes
9
-
10
- ITERATIONS = 100
11
-
12
- def run_benchmark_and_print_results(data, run_benchmark_func)
13
- puts ""
14
- puts "Using %s total events in a batch" % [data[0].size]
15
- puts ""
16
-
17
- result = []
18
- ITERATIONS.times do |i|
19
- result << Benchmark.measure { run_benchmark_func.(data[i]) }
20
- end
21
-
22
- sum = result.inject(nil) { |sum, t| sum.nil? ? sum = t : sum += t }
23
- avg = sum / result.size
24
-
25
- Benchmark.bm(7, "sum:", "avg:") do |b|
26
- [sum, avg]
27
- end
28
- puts ""
29
- end
30
-
31
- # Generate random event with only single event having special server host attribute set which
32
- # represents a worst case scenario since we need to backfill rest of the events.
33
- def generate_events(count)
34
- result = []
35
-
36
- ITERATIONS.times do |iteration|
37
- events = []
38
-
39
- count.times do |index|
40
- event = generate_hash([2])
41
- event[:attrs] = Hash.new
42
- event[:log] = 1
43
-
44
- if index == count - 1
45
- event[:attrs][EVENT_LEVEL_SERVER_HOST_ATTRIBUTE_NAME] = format("test-host-%s", index)
46
- end
47
-
48
- events << event
49
- end
50
-
51
- raise "Assertion failed" unless events.size == count
52
-
53
- result << events
54
- end
55
-
56
- raise "Assertion failed" unless result.size == ITERATIONS
57
- result
58
- end
59
-
60
- def run_func(events)
61
- # NOTE: This function manipulates events in place
62
- events.each_with_index do |event, index|
63
- if index < events.size - 1
64
- # Last event will have _origServerHost set, but others won't
65
- raise "Assertion failed" unless event[:attrs][EVENT_LEVEL_SERVER_HOST_ATTRIBUTE_NAME].nil?
66
- end
67
- end
68
-
69
- Scalyr::Common::Util.set_session_level_serverhost_on_events("session-server-host-dummy", events, {}, true)
70
-
71
- events.each do |event|
72
- raise "Assertion failed" unless event[:attrs][EVENT_LEVEL_SERVER_HOST_ATTRIBUTE_NAME].nil? == false
73
- end
74
- end
75
-
76
-
77
- puts "Using %s iterations" % [ITERATIONS]
78
- puts ""
79
-
80
- @value = Quantile::Estimator.new
81
-
82
- puts "Util.set_session_level_serverhost_on_events()"
83
- puts "==============================="
84
-
85
- # 100 events in a batch
86
- data = generate_events(100)
87
- run_benchmark_and_print_results(data, method(:run_func))
88
-
89
- # 500 events in a batch
90
- data = generate_events(500)
91
- run_benchmark_and_print_results(data, method(:run_func))
92
-
93
- # 1000 events in a batch
94
- data = generate_events(1000)
95
- run_benchmark_and_print_results(data, method(:run_func))
96
-
97
- # 2000 events in a batch
98
- data = generate_events(2000)
99
- run_benchmark_and_print_results(data, method(:run_func))
100
-
101
- # 3000 events in a batch
102
- data = generate_events(3000)
103
- run_benchmark_and_print_results(data, method(:run_func))
104
-
105
- # 5000 events in a batch
106
- data = generate_events(5000)
107
- run_benchmark_and_print_results(data, method(:run_func))
@@ -1,24 +0,0 @@
1
- def rand_str(len)
2
- return (0...len).map { (65 + rand(26)).chr }.join
3
- end
4
-
5
- def generate_hash(widths)
6
- result = {}
7
- if widths.empty?
8
- return rand_str(20)
9
- else
10
- widths[0].times do
11
- result[rand_str(9)] = generate_hash(widths[1..widths.length])
12
- end
13
- return result
14
- end
15
- end
16
-
17
- def generate_data_array_for_spec(spec)
18
- data = []
19
- ITERATIONS.times do
20
- data << generate_hash(spec)
21
- end
22
-
23
- data
24
- end
@@ -1,337 +0,0 @@
1
- # encoding: utf-8
2
- require "logstash/devutils/rspec/spec_helper"
3
- require "logstash/outputs/scalyr"
4
- require "logstash/codecs/plain"
5
- require "logstash/event"
6
- require "json"
7
- require 'webmock/rspec'
8
-
9
- # Require the specific version of `json` used in logstash
10
- gem 'json', '1.8.6'
11
- require 'json'
12
-
13
- WebMock.allow_net_connect!
14
-
15
- RSpec.configure do |rspec|
16
- rspec.expect_with :rspec do |c|
17
- c.max_formatted_output_length = nil
18
- end
19
- end
20
-
21
- describe LogStash::Outputs::Scalyr do
22
- let(:sample_events) {
23
- events = []
24
- for i in 1..3 do
25
- e = LogStash::Event.new
26
- e.set('source_host', "my host #{i}")
27
- e.set('source_file', "my file #{i}")
28
- e.set('seq', i)
29
- e.set('nested', {'a'=>1, 'b'=>[3,4,5]})
30
- e.set('tags', ['t1', 't2', 't3'])
31
- events.push(e)
32
- end
33
- events
34
- }
35
-
36
- describe "#ssl_tests" do
37
- context "with default SSL configuration" do
38
- it "throws a ServerError due to fake api key" do
39
- plugin = LogStash::Outputs::Scalyr.new({
40
- 'api_write_token' => '1234',
41
- 'perform_connectivity_check' => false,
42
- 'max_retries' => 2,
43
- 'retry_max_interval' => 2,
44
- 'retry_initial_interval' => 0.2,
45
- })
46
- plugin.register
47
- plugin.instance_variable_set(:@running, false)
48
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
49
- plugin.multi_receive(sample_events)
50
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
51
- {
52
- :error_class=>"Scalyr::Common::Client::ServerError",
53
- :batch_num=>1,
54
- :code=>401,
55
- :message=>"error/client/badParam",
56
- :payload_size=>737,
57
- :record_count=>3,
58
- :total_batches=>1,
59
- :url=>"https://agent.scalyr.com/addEvents",
60
- :will_retry_in_seconds=>0.4,
61
- :body=>"{\n \"message\": \"Couldn't decode API token ...234.\",\n \"status\": \"error/client/badParam\"\n}"
62
- }
63
- )
64
- end
65
- end
66
-
67
- context "when pointing at a location without any valid certs and not using builtin" do
68
- it "throws an SSLError" do
69
- plugin = LogStash::Outputs::Scalyr.new({
70
- 'api_write_token' => '1234',
71
- 'perform_connectivity_check' => false,
72
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
73
- 'append_builtin_cert' => false,
74
- 'max_retries' => 2,
75
- 'retry_max_interval' => 2,
76
- 'retry_initial_interval' => 0.2,
77
- })
78
- plugin.register
79
- plugin.instance_variable_set(:@running, false)
80
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
81
- plugin.multi_receive(sample_events)
82
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
83
- {
84
- :error_class=>"Manticore::UnknownException",
85
- :batch_num=>1,
86
- :message=>"Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
87
- #:message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
88
- :payload_size=>737,
89
- :record_count=>3,
90
- :total_batches=>1,
91
- :url=>"https://agent.scalyr.com/addEvents",
92
- :will_retry_in_seconds=>0.4
93
- }
94
- )
95
- end
96
- end
97
-
98
- context "when system certs are missing and not using builtin" do
99
- it "throws an SSLError" do
100
- `sudo mv #{OpenSSL::X509::DEFAULT_CERT_FILE} /tmp/system_cert.pem`
101
- `sudo mv #{OpenSSL::X509::DEFAULT_CERT_DIR} /tmp/system_certs`
102
-
103
- begin
104
- plugin = LogStash::Outputs::Scalyr.new({
105
- 'api_write_token' => '1234',
106
- 'perform_connectivity_check' => false,
107
- 'append_builtin_cert' => false,
108
- 'max_retries' => 2,
109
- 'retry_max_interval' => 2,
110
- 'retry_initial_interval' => 0.2,
111
- })
112
- plugin.register
113
- plugin.instance_variable_set(:@running, false)
114
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
115
- plugin.multi_receive(sample_events)
116
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
117
- {
118
- :error_class=>"Manticore::UnknownException",
119
- :batch_num=>1,
120
- :message=>"Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
121
- #:message=>"java.lang.RuntimeException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty",
122
- :payload_size=>737,
123
- :record_count=>3,
124
- :total_batches=>1,
125
- :url=>"https://agent.scalyr.com/addEvents",
126
- :will_retry_in_seconds=>0.4
127
- }
128
- )
129
- end
130
- ensure
131
- `sudo mv /tmp/system_certs #{OpenSSL::X509::DEFAULT_CERT_DIR}`
132
- `sudo mv /tmp/system_cert.pem #{OpenSSL::X509::DEFAULT_CERT_FILE}`
133
- end
134
- end
135
-
136
- context "when server hostname doesn't match the cert" do
137
- it "throws an SSLError" do
138
- agent_scalyr_com_ip = `dig +short agent.scalyr.com 2> /dev/null | tail -n 1 | tr -d "\n"`
139
- if agent_scalyr_com_ip.empty?
140
- agent_scalyr_com_ip = `getent hosts agent.scalyr.com \
141
- | awk '{ print $1 }' | tail -n 1 | tr -d "\n"`
142
- end
143
- mock_host = "invalid.mitm.should.fail.test.agent.scalyr.com"
144
- etc_hosts_entry = "#{agent_scalyr_com_ip} #{mock_host}"
145
- hosts_bkp = `sudo cat /etc/hosts`
146
- hosts_bkp = hosts_bkp.chomp
147
- # Add mock /etc/hosts entry and config scalyr_server entry
148
- `echo "#{etc_hosts_entry}" | sudo tee -a /etc/hosts`
149
-
150
- begin
151
- plugin = LogStash::Outputs::Scalyr.new({
152
- 'api_write_token' => '1234',
153
- 'perform_connectivity_check' => false,
154
- 'scalyr_server' => 'https://invalid.mitm.should.fail.test.agent.scalyr.com:443',
155
- 'max_retries' => 2,
156
- 'retry_max_interval' => 2,
157
- 'retry_initial_interval' => 0.2,
158
- })
159
- plugin.register
160
- plugin.instance_variable_set(:@running, false)
161
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
162
- plugin.multi_receive(sample_events)
163
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
164
- {
165
- :error_class=>"Manticore::UnknownException",
166
- :batch_num=>1,
167
- :message=>"Certificate for <invalid.mitm.should.fail.test.agent.scalyr.com> doesn't match any of the subject alternative names: [*.scalyr.com, scalyr.com]",
168
- :payload_size=>737,
169
- :record_count=>3,
170
- :total_batches=>1,
171
- :url=>"https://invalid.mitm.should.fail.test.agent.scalyr.com/addEvents",
172
- :will_retry_in_seconds=>0.4
173
- }
174
- )
175
- ensure
176
- # Clean up the hosts file
177
- `sudo truncate -s 0 /etc/hosts`
178
- `echo "#{hosts_bkp}" | sudo tee -a /etc/hosts`
179
- end
180
- end
181
- end
182
-
183
- context "when an error occurs with retries at 15" do
184
- it "exits after 5 retries and emits a log" do
185
- plugin = LogStash::Outputs::Scalyr.new({
186
- 'api_write_token' => '1234',
187
- 'perform_connectivity_check' => false,
188
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
189
- 'append_builtin_cert' => false,
190
- 'max_retries' => 15,
191
- 'retry_max_interval' => 0.5,
192
- 'retry_initial_interval' => 0.2,
193
- })
194
- plugin.register
195
- allow(plugin.instance_variable_get(:@logger)).to receive(:error)
196
- plugin.multi_receive(sample_events)
197
- expect(plugin.instance_variable_get(:@logger)).to have_received(:error).with("Failed to send 3 events after 15 tries.", anything
198
- )
199
- end
200
- end
201
- end
202
-
203
- describe "response_handling_tests" do
204
- context "when receiving a 503 response" do
205
- it "don't throw an error but do log one to debug" do
206
- stub_request(:post, "https://agent.scalyr.com/addEvents").
207
- to_return(status: 503, body: "stubbed response", headers: {})
208
-
209
- plugin = LogStash::Outputs::Scalyr.new({
210
- 'api_write_token' => '1234',
211
- 'perform_connectivity_check' => false,
212
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
213
- 'append_builtin_cert' => false,
214
- 'max_retries' => 2,
215
- 'retry_max_interval' => 2,
216
- 'retry_initial_interval' => 0.2,
217
- })
218
- plugin.register
219
- plugin.instance_variable_set(:@running, false)
220
-
221
- allow(plugin.instance_variable_get(:@logger)).to receive(:debug)
222
- plugin.multi_receive(sample_events)
223
- expect(plugin.instance_variable_get(:@logger)).to have_received(:debug).with("Error uploading to Scalyr (will backoff-retry)",
224
- {
225
- :error_class=>"Scalyr::Common::Client::ServerError",
226
- :batch_num=>1,
227
- :code=>503,
228
- :message=>"Invalid JSON response from server",
229
- :payload_size=>737,
230
- :record_count=>3,
231
- :total_batches=>1,
232
- :url=>"https://agent.scalyr.com/addEvents",
233
- :will_retry_in_seconds=>0.4,
234
- :body=>"stubbed response"
235
- }
236
- )
237
- end
238
- end
239
-
240
- context "when receiving a 500 response" do
241
- it "don't throw an error but do log one to error" do
242
- stub_request(:post, "https://agent.scalyr.com/addEvents").
243
- to_return(status: 500, body: "stubbed response", headers: {})
244
-
245
- plugin = LogStash::Outputs::Scalyr.new({
246
- 'api_write_token' => '1234',
247
- 'perform_connectivity_check' => false,
248
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
249
- 'append_builtin_cert' => false,
250
- 'max_retries' => 2,
251
- 'retry_max_interval' => 2,
252
- 'retry_initial_interval' => 0.2,
253
- })
254
- plugin.register
255
- plugin.instance_variable_set(:@running, false)
256
-
257
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
258
- plugin.multi_receive(sample_events)
259
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
260
- {
261
- :error_class=>"Scalyr::Common::Client::ServerError",
262
- :batch_num=>1,
263
- :code=>500,
264
- :message=>"Invalid JSON response from server",
265
- :payload_size=>737,
266
- :record_count=>3,
267
- :total_batches=>1,
268
- :url=>"https://agent.scalyr.com/addEvents",
269
- :will_retry_in_seconds=>0.4,
270
- :body=>"stubbed response"
271
- }
272
- )
273
- end
274
- end
275
-
276
- context "when receiving a long non-json response" do
277
- it "don't throw an error but do log one to error" do
278
- stub_request(:post, "https://agent.scalyr.com/addEvents").
279
- to_return(status: 500, body: "0123456789" * 52, headers: {})
280
-
281
- plugin = LogStash::Outputs::Scalyr.new({
282
- 'api_write_token' => '1234',
283
- 'perform_connectivity_check' => false,
284
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
285
- 'append_builtin_cert' => false,
286
- 'max_retries' => 2,
287
- 'retry_max_interval' => 2,
288
- 'retry_initial_interval' => 0.2,
289
- })
290
- plugin.register
291
- plugin.instance_variable_set(:@running, false)
292
-
293
- allow(plugin.instance_variable_get(:@logger)).to receive(:warn)
294
- plugin.multi_receive(sample_events)
295
- expect(plugin.instance_variable_get(:@logger)).to have_received(:warn).with("Error uploading to Scalyr (will backoff-retry)",
296
- {
297
- :error_class=>"Scalyr::Common::Client::ServerError",
298
- :batch_num=>1,
299
- :code=>500,
300
- :message=>"Invalid JSON response from server",
301
- :payload_size=>737,
302
- :record_count=>3,
303
- :total_batches=>1,
304
- :url=>"https://agent.scalyr.com/addEvents",
305
- :will_retry_in_seconds=>0.4,
306
- :body=>("0123456789" * 50) + "012345678..."
307
- }
308
- )
309
- end
310
- end
311
-
312
- context 'when DLQ is enabled' do
313
- let(:dlq_writer) { double('DLQ writer') }
314
- it 'should send the event to the DLQ' do
315
- stub_request(:post, "https://agent.scalyr.com/addEvents").
316
- to_return(status: 500, body: "stubbed response", headers: {})
317
-
318
- plugin = LogStash::Outputs::Scalyr.new({
319
- 'api_write_token' => '1234',
320
- 'perform_connectivity_check' => false,
321
- 'ssl_ca_bundle_path' => '/fakepath/nocerts',
322
- 'append_builtin_cert' => false,
323
- 'max_retries' => 2,
324
- 'retry_max_interval' => 2,
325
- 'retry_initial_interval' => 0.2,
326
- })
327
- plugin.register
328
- plugin.instance_variable_set(:@running, false)
329
- plugin.instance_variable_set('@dlq_writer', dlq_writer)
330
-
331
- expect(dlq_writer).to receive(:write).exactly(3).times.with(anything, anything)
332
- plugin.multi_receive(sample_events)
333
- end
334
- end
335
- end
336
-
337
- end