logstash-output-scalyr 0.1.17.beta → 0.1.18.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +1 -1
- data/lib/logstash/outputs/scalyr.rb +22 -2
- data/lib/scalyr/common/util.rb +10 -5
- data/lib/scalyr/constants.rb +1 -1
- data/logstash-output-scalyr.gemspec +1 -1
- data/spec/logstash/outputs/scalyr_spec.rb +35 -3
- data/spec/scalyr/common/util_spec.rb +64 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9099fcf20201bf8e3905273393a38bb1addefb219e1874a45a439bbfd2dcddbd
|
4
|
+
data.tar.gz: a031faa8657951b66a09c172f6be69b774a2192e661ef99370813abe62250cbb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c25cad81473d0224fb5c75558e302f6383d69361d3263aeaf0fe619b8c2a3a6866bf0eaf811588b9235edb4e15e11a2d0b95ecb99e2a3045ee6c6e66998e1627
|
7
|
+
data.tar.gz: fed7e02e32c70ce199dbd7ec5841711ff77c65d3a56ebe53eeada8c165d5b8fa603fc15b3c00e0e397682a50899dd141bfdcacdcbb97244e2b26205c92802238
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Beta
|
2
2
|
|
3
|
+
## 0.1.18.beta
|
4
|
+
- Add metrics for successfully sent and failed logstash events, and retries.
|
5
|
+
- Make array flattening optional during nested value flattening with the `flatten_nested_arrays` configuration option.
|
6
|
+
|
3
7
|
## 0.1.17.beta
|
4
8
|
- Catch errors relating to Bignum conversions present in the ``json`` library and manually convert to string as
|
5
9
|
a workaround.
|
data/README.md
CHANGED
@@ -10,7 +10,7 @@ You can view documentation for this plugin [on the Scalyr website](https://app.s
|
|
10
10
|
# Quick start
|
11
11
|
|
12
12
|
1. Build the gem, run `gem build logstash-output-scalyr.gemspec`
|
13
|
-
2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.1.
|
13
|
+
2. Install the gem into a Logstash installation, run `/usr/share/logstash/bin/logstash-plugin install logstash-output-scalyr-0.1.18.beta.gem` or follow the latest official instructions on working with plugins from Logstash.
|
14
14
|
3. Configure the output plugin (e.g. add it to a pipeline .conf)
|
15
15
|
4. Restart Logstash
|
16
16
|
|
@@ -68,7 +68,8 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
68
68
|
# If true, nested values will be flattened (which changes keys to delimiter-separated concatenation of all
|
69
69
|
# nested keys).
|
70
70
|
config :flatten_nested_values, :validate => :boolean, :default => false
|
71
|
-
config :flatten_nested_values_delimiter, :validate => :string, :default => "_"
|
71
|
+
config :flatten_nested_values_delimiter, :validate => :string, :default => "_"
|
72
|
+
config :flatten_nested_arrays, :validate => :boolean, :default => true
|
72
73
|
|
73
74
|
# If true, the 'tags' field will be flattened into key-values where each key is a tag and each value is set to
|
74
75
|
# :flat_tag_value
|
@@ -241,6 +242,10 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
241
242
|
# level metrics are handled by the HTTP Client class.
|
242
243
|
@multi_receive_statistics = {
|
243
244
|
:total_multi_receive_secs => 0,
|
245
|
+
:total_events_processed => 0,
|
246
|
+
:successful_events_processed => 0,
|
247
|
+
:failed_events_processed => 0,
|
248
|
+
:total_retry_count => 0,
|
244
249
|
:total_java_class_cast_errors => 0
|
245
250
|
}
|
246
251
|
@plugin_metrics = get_new_metrics
|
@@ -345,6 +350,9 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
345
350
|
sleep_interval = sleep_for(sleep_interval)
|
346
351
|
exc_sleep += sleep_interval
|
347
352
|
exc_retries += 1
|
353
|
+
@stats_lock.synchronize do
|
354
|
+
@multi_receive_statistics[:total_retry_count] += 1
|
355
|
+
end
|
348
356
|
message = "Error uploading to Scalyr (will backoff-retry)"
|
349
357
|
exc_data = {
|
350
358
|
:error_class => e.e_class,
|
@@ -394,11 +402,19 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
394
402
|
}
|
395
403
|
exc_sleep += sleep_interval
|
396
404
|
exc_retries += 1
|
405
|
+
@stats_lock.synchronize do
|
406
|
+
@multi_receive_statistics[:total_retry_count] += 1
|
407
|
+
end
|
397
408
|
retry if @running and exc_retries < @max_retries
|
398
409
|
log_retry_failure(multi_event_request, exc_data, exc_retries, exc_sleep)
|
399
410
|
next
|
400
411
|
end
|
401
412
|
|
413
|
+
@stats_lock.synchronize do
|
414
|
+
@multi_receive_statistics[:total_events_processed] += multi_event_request[:logstash_events].length
|
415
|
+
@multi_receive_statistics[:successful_events_processed] += multi_event_request[:logstash_events].length
|
416
|
+
end
|
417
|
+
|
402
418
|
if !exc_data.nil?
|
403
419
|
message = "Retry successful after error."
|
404
420
|
if exc_commonly_retried
|
@@ -437,6 +453,10 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
437
453
|
|
438
454
|
|
439
455
|
def log_retry_failure(multi_event_request, exc_data, exc_retries, exc_sleep)
|
456
|
+
@stats_lock.synchronize do
|
457
|
+
@multi_receive_statistics[:total_events_processed] += multi_event_request[:logstash_events].length
|
458
|
+
@multi_receive_statistics[:failed_events_processed] += multi_event_request[:logstash_events].length
|
459
|
+
end
|
440
460
|
message = "Failed to send #{multi_event_request[:logstash_events].length} events after #{exc_retries} tries."
|
441
461
|
sample_events = Array.new
|
442
462
|
multi_event_request[:logstash_events][0,5].each {|l_event|
|
@@ -612,7 +632,7 @@ class LogStash::Outputs::Scalyr < LogStash::Outputs::Base
|
|
612
632
|
# flatten record
|
613
633
|
if @flatten_nested_values
|
614
634
|
start_time = Time.now.to_f
|
615
|
-
record = Scalyr::Common::Util.flatten(record, delimiter=@flatten_nested_values_delimiter)
|
635
|
+
record = Scalyr::Common::Util.flatten(record, delimiter=@flatten_nested_values_delimiter, flatten_arrays=@flatten_nested_arrays)
|
616
636
|
end_time = Time.now.to_f
|
617
637
|
flatten_nested_values_duration = end_time - start_time
|
618
638
|
end
|
data/lib/scalyr/common/util.rb
CHANGED
@@ -4,7 +4,7 @@ module Scalyr; module Common; module Util;
|
|
4
4
|
# Flattens a hash or array, returning a hash where keys are a delimiter-separated string concatenation of all
|
5
5
|
# nested keys. Returned keys are always strings. If a non-hash or array is provided, raises TypeError.
|
6
6
|
# Please see rspec util_spec.rb for expected behavior.
|
7
|
-
def self.flatten(obj, delimiter='_')
|
7
|
+
def self.flatten(obj, delimiter='_', flatten_arrays=true)
|
8
8
|
|
9
9
|
# base case is input object is not enumerable, in which case simply return it
|
10
10
|
if !obj.respond_to?(:each)
|
@@ -19,8 +19,8 @@ def self.flatten(obj, delimiter='_')
|
|
19
19
|
|
20
20
|
# input object is a hash
|
21
21
|
obj.each do |key, value|
|
22
|
-
if value.respond_to?(:each)
|
23
|
-
flatten(value).each do |subkey, subvalue|
|
22
|
+
if (flatten_arrays and value.respond_to?(:each)) or value.respond_to?(:has_key?)
|
23
|
+
flatten(value, delimiter, flatten_arrays).each do |subkey, subvalue|
|
24
24
|
result["#{key}#{delimiter}#{subkey}"] = subvalue
|
25
25
|
end
|
26
26
|
else
|
@@ -28,18 +28,23 @@ def self.flatten(obj, delimiter='_')
|
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
elsif flatten_arrays
|
32
32
|
|
33
33
|
# input object is an array or set
|
34
34
|
obj.each_with_index do |value, index|
|
35
35
|
if value.respond_to?(:each)
|
36
|
-
flatten(value).each do |subkey, subvalue|
|
36
|
+
flatten(value, delimiter, flatten_arrays).each do |subkey, subvalue|
|
37
37
|
result["#{index}#{delimiter}#{subkey}"] = subvalue
|
38
38
|
end
|
39
39
|
else
|
40
40
|
result["#{index}"] = value
|
41
41
|
end
|
42
42
|
end
|
43
|
+
|
44
|
+
else
|
45
|
+
|
46
|
+
result = obj
|
47
|
+
|
43
48
|
end
|
44
49
|
|
45
50
|
return result
|
data/lib/scalyr/constants.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
PLUGIN_VERSION = "v0.1.
|
2
|
+
PLUGIN_VERSION = "v0.1.18.beta"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-scalyr'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.18.beta'
|
4
4
|
s.licenses = ['Apache-2.0']
|
5
5
|
s.summary = "Scalyr output plugin for Logstash"
|
6
6
|
s.description = "Sends log data collected by Logstash to Scalyr (https://www.scalyr.com)"
|
@@ -273,9 +273,41 @@ describe LogStash::Outputs::Scalyr do
|
|
273
273
|
expect(body['events'].size).to eq(3)
|
274
274
|
expect(body['events'][2]['attrs']).to eq({
|
275
275
|
"nested.a" => 1,
|
276
|
-
"nested.
|
277
|
-
"nested.
|
278
|
-
"nested.
|
276
|
+
"nested.b.0" => 3,
|
277
|
+
"nested.b.1" => 4,
|
278
|
+
"nested.b.2" => 5,
|
279
|
+
'seq' => 3,
|
280
|
+
'source_file' => 'my file 3',
|
281
|
+
'source_host' => 'my host 3',
|
282
|
+
'serverHost' => 'Logstash',
|
283
|
+
"tag_prefix_t1" => "true",
|
284
|
+
"tag_prefix_t2" => "true",
|
285
|
+
"tag_prefix_t3" => "true",
|
286
|
+
"parser" => "logstashParser",
|
287
|
+
})
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context "when configured to flatten values with custom delimiter, no array flattening" do
|
292
|
+
config = {
|
293
|
+
'api_write_token' => '1234',
|
294
|
+
'flatten_tags' => true,
|
295
|
+
'flat_tag_value' => 'true',
|
296
|
+
'flat_tag_prefix' => 'tag_prefix_',
|
297
|
+
'flatten_nested_values' => true, # this converts into string 'true'
|
298
|
+
'flatten_nested_arrays' => false,
|
299
|
+
'flatten_nested_values_delimiter' => ".",
|
300
|
+
}
|
301
|
+
plugin = LogStash::Outputs::Scalyr.new(config)
|
302
|
+
it "flattens nested values with a period" do
|
303
|
+
allow(plugin).to receive(:send_status).and_return(nil)
|
304
|
+
plugin.register
|
305
|
+
result = plugin.build_multi_event_request_array(sample_events)
|
306
|
+
body = JSON.parse(result[0][:body])
|
307
|
+
expect(body['events'].size).to eq(3)
|
308
|
+
expect(body['events'][2]['attrs']).to eq({
|
309
|
+
"nested.a" => 1,
|
310
|
+
"nested.b" => [3, 4, 5],
|
279
311
|
'seq' => 3,
|
280
312
|
'source_file' => 'my file 3',
|
281
313
|
'source_host' => 'my host 3',
|
@@ -132,6 +132,70 @@ describe Scalyr::Common::Util do
|
|
132
132
|
expect(Scalyr::Common::Util.flatten(din)).to eq(dout)
|
133
133
|
end
|
134
134
|
|
135
|
+
it "flattens a single-level array, no array flattening" do
|
136
|
+
din = [1, 2, 3]
|
137
|
+
dout = [1, 2, 3]
|
138
|
+
expect(Scalyr::Common::Util.flatten(din, "_", flatten_arrays=false)).to eq(dout)
|
139
|
+
end
|
140
|
+
|
141
|
+
it "flattens a multi-level array, no array flattening" do
|
142
|
+
din = ['a', 'b', ['c', ['d', 'e', 'f'], 'g'], 'h', 'i']
|
143
|
+
dout = ['a', 'b', ['c', ['d', 'e', 'f'], 'g'], 'h', 'i']
|
144
|
+
expect(Scalyr::Common::Util.flatten(din, "_", flatten_arrays=false)).to eq(dout)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "flattens a hash that contains an array, no array flattening" do
|
148
|
+
din = {
|
149
|
+
'a' => 1,
|
150
|
+
'c' => [100, 200, 300]
|
151
|
+
}
|
152
|
+
dout = {
|
153
|
+
'a' => 1,
|
154
|
+
'c' => [100, 200, 300]
|
155
|
+
}
|
156
|
+
expect(Scalyr::Common::Util.flatten(din, "_", flatten_arrays=false)).to eq(dout)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "flattens a hash that contains an array that contains a hash, no array flattening" do
|
160
|
+
din = {
|
161
|
+
'a' => 1,
|
162
|
+
'c' => [
|
163
|
+
100,
|
164
|
+
{'d' => 1000, 'e' => 2000},
|
165
|
+
300
|
166
|
+
]
|
167
|
+
}
|
168
|
+
dout = {
|
169
|
+
'a' => 1,
|
170
|
+
'c' => [
|
171
|
+
100,
|
172
|
+
{'d' => 1000, 'e' => 2000},
|
173
|
+
300
|
174
|
+
]
|
175
|
+
}
|
176
|
+
expect(Scalyr::Common::Util.flatten(din, "_", flatten_arrays=false)).to eq(dout)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "flattens a hash that contains an array that contains a hash that contains an array, no array flattening" do
|
180
|
+
din = {
|
181
|
+
'a' => 1,
|
182
|
+
'c' => [
|
183
|
+
100,
|
184
|
+
{'d' => 1000, 'e' => 2000, 'f' => [4, 5, 6]},
|
185
|
+
300
|
186
|
+
]
|
187
|
+
}
|
188
|
+
dout = {
|
189
|
+
'a' => 1,
|
190
|
+
'c' => [
|
191
|
+
100,
|
192
|
+
{'d' => 1000, 'e' => 2000, 'f' => [4, 5, 6]},
|
193
|
+
300
|
194
|
+
]
|
195
|
+
}
|
196
|
+
expect(Scalyr::Common::Util.flatten(din, "_", flatten_arrays=false)).to eq(dout)
|
197
|
+
end
|
198
|
+
|
135
199
|
it "accepts custom delimiters" do
|
136
200
|
din = {
|
137
201
|
'a' => 1,
|