logstash-output-qingstor 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/logstash/outputs/qingstor/multipart_uploader.rb +1 -1
- data/lib/logstash/outputs/qingstor/rotation_policy.rb +13 -4
- data/lib/logstash/outputs/qingstor/uploader.rb +2 -2
- data/lib/logstash/outputs/qingstor.rb +15 -10
- data/logstash-output-qingstor.gemspec +1 -1
- data/spec/outputs/qingstor/rotation_policy_spec.rb +30 -10
- 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: 3c17d2f3c3498c58c9a99bfb78fb39e1dec09d1dd72d8a4c8c56c0c1ea500855
|
4
|
+
data.tar.gz: dc01d1554f162363e75876155f0338b1efb740804cd673fd8afc047f51f02b71
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0c23b81601ac731bccb9214d45b67f9b44917947afa7de30e264972ace16720c4b1e8d309beefda4b97f8f1d5cdbe550d5504e3d19fdb1c8ec6adc53979792dc
|
7
|
+
data.tar.gz: 5c06847d78b3f526b0ca671561923964a28a55f096f7dd17d73c66a2d56afa53b433eedcf93373a3e1a7a47c5006a89a3b69aa472e01381f16145b2c0853923e
|
data/CHANGELOG.md
CHANGED
@@ -64,7 +64,7 @@ module LogStash
|
|
64
64
|
object_parts = (0..last_part_number).to_a.map {|x| {'part_number' => x}}
|
65
65
|
@upload_headers['object_parts'] = object_parts
|
66
66
|
res = @bucket.complete_multipart_upload(@object.key, @upload_headers)
|
67
|
-
@logger.
|
67
|
+
@logger.info('multipart uploading completed', :file => @object.key)
|
68
68
|
end
|
69
69
|
|
70
70
|
def calculate_segment
|
@@ -7,10 +7,6 @@ module LogStash
|
|
7
7
|
class Qingstor
|
8
8
|
class RotationPolicy
|
9
9
|
class Policy
|
10
|
-
def to_s
|
11
|
-
name
|
12
|
-
end
|
13
|
-
|
14
10
|
def name
|
15
11
|
self.class.name.split('::').last.downcase
|
16
12
|
end
|
@@ -36,6 +32,10 @@ module LogStash
|
|
36
32
|
def rotate?(file)
|
37
33
|
!file.empty? && (::Time.now - file.ctime) >= @file_time
|
38
34
|
end
|
35
|
+
|
36
|
+
def to_s
|
37
|
+
{ :policy => name, :file_time => @file_time }.to_s
|
38
|
+
end
|
39
39
|
end
|
40
40
|
|
41
41
|
class Size < Policy
|
@@ -49,6 +49,10 @@ module LogStash
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def needs_periodic?; false; end
|
52
|
+
|
53
|
+
def to_s
|
54
|
+
{ :policy => name, :file_size => @file_size }.to_s
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
class SizeAndTime < Policy
|
@@ -61,6 +65,11 @@ module LogStash
|
|
61
65
|
(!file.empty? && (::Time.now - file.ctime) >= @file_time) ||
|
62
66
|
(file.size >= @file_size)
|
63
67
|
end
|
68
|
+
|
69
|
+
def to_s
|
70
|
+
{ :policy => name, :file_time => @file_time,
|
71
|
+
:file_size => @file_size }.to_s
|
72
|
+
end
|
64
73
|
end
|
65
74
|
|
66
75
|
def Policy(policy, file_size, file_time)
|
@@ -39,13 +39,13 @@ module LogStash
|
|
39
39
|
upload_headers = process_encrypt_options(upload_options)
|
40
40
|
|
41
41
|
if file.size > 50 * 1024 * 1024
|
42
|
-
@logger.
|
42
|
+
@logger.info('Multipart uploading file', :file => file.key)
|
43
43
|
multipart_uploader = MultipartUploader.new(@bucket, @logger, file, upload_headers)
|
44
44
|
multipart_uploader.upload
|
45
45
|
else
|
46
46
|
upload_headers['content_md5'] = Digest::MD5.file(file.path).to_s
|
47
47
|
upload_headers['body'] = ::File.read(file.path)
|
48
|
-
@logger.
|
48
|
+
@logger.info('Uploading file', :file => file.key)
|
49
49
|
@bucket.put_object(file.key, upload_headers)
|
50
50
|
end
|
51
51
|
|
@@ -105,16 +105,13 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
105
105
|
|
106
106
|
def register
|
107
107
|
QingstorValidator.prefix_valid?(@prefix) unless @prefix.nil?
|
108
|
-
|
109
108
|
unless directory_valid?(@tmpdir)
|
110
109
|
raise LogStash::ConfigurationError,
|
111
110
|
"Logstash must have the permissions to write to: #{@tmpdir}"
|
112
111
|
end
|
113
112
|
|
114
113
|
@file_repository = FileRepository.new(@tags, @encoding, @tmpdir)
|
115
|
-
|
116
114
|
@rotation = RotationPolicy.new(@rotation_strategy, @file_size, @file_time)
|
117
|
-
|
118
115
|
executor = Concurrent::ThreadPoolExecutor.new(
|
119
116
|
:min_threads => 1,
|
120
117
|
:max_threads => @upload_workers_count,
|
@@ -124,14 +121,22 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
124
121
|
|
125
122
|
@qs_bucket = getbucket
|
126
123
|
QingstorValidator.bucket_valid?(@qs_bucket)
|
127
|
-
|
128
124
|
@uploader = Uploader.new(@qs_bucket, @logger, executor)
|
129
125
|
|
126
|
+
log_print_config
|
130
127
|
start_periodic_check if @rotation.needs_periodic?
|
131
|
-
|
132
128
|
restore_from_crash if @restore
|
133
129
|
end # def register
|
134
130
|
|
131
|
+
def log_print_config
|
132
|
+
@logger.info('Run at setting: ', :prefix => @prefix,
|
133
|
+
:tmpdir => @tmpdir,
|
134
|
+
:rotation => @rotation.to_s,
|
135
|
+
:tags => @tags,
|
136
|
+
:encoding => @encoding,
|
137
|
+
:restore => @restore)
|
138
|
+
end
|
139
|
+
|
135
140
|
def multi_receive_encoded(events_and_encoded)
|
136
141
|
prefix_written_to = Set.new
|
137
142
|
|
@@ -191,7 +196,7 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
191
196
|
def close
|
192
197
|
stop_periodic_check if @rotation.needs_periodic?
|
193
198
|
|
194
|
-
@logger.
|
199
|
+
@logger.info('uploading current workspace before closing')
|
195
200
|
@file_repository.each_files do |file|
|
196
201
|
upload_file(file) if file.size > 0
|
197
202
|
end
|
@@ -217,12 +222,12 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
217
222
|
end
|
218
223
|
|
219
224
|
def clean_temporary_file(file)
|
220
|
-
@logger.
|
225
|
+
@logger.info('Callback: removing temporary file', :file => file.path)
|
221
226
|
file.delete!
|
222
227
|
end
|
223
228
|
|
224
229
|
def start_periodic_check
|
225
|
-
@logger.
|
230
|
+
@logger.info('Start periodic rotation check')
|
226
231
|
|
227
232
|
@periodic_check = Concurrent::TimerTask.new(
|
228
233
|
:execution_interval => PERIODIC_CHECK_INTERVAL_IN_SECONDS
|
@@ -259,7 +264,7 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
259
264
|
# Now multipart uploader supports file size up to 500GB
|
260
265
|
if temp_file.size > 0
|
261
266
|
temp_file.key = 'Restored/' + Time.new.strftime('%Y-%m-%d/') + temp_file.key
|
262
|
-
@logger.
|
267
|
+
@logger.info('Recoving from crash and uploading',
|
263
268
|
:file => temp_file.key)
|
264
269
|
@crash_uploader.upload_async(
|
265
270
|
temp_file,
|
@@ -267,7 +272,7 @@ class LogStash::Outputs::Qingstor < LogStash::Outputs::Base
|
|
267
272
|
:upload_options => upload_options
|
268
273
|
)
|
269
274
|
elsif temp_file.size == 0
|
270
|
-
@logger.
|
275
|
+
@logger.info('Recoving from crash, delete empty files',
|
271
276
|
:file => temp_file.path)
|
272
277
|
temp_file.delete!
|
273
278
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'logstash-output-qingstor'
|
3
|
-
s.version = '0.3.
|
3
|
+
s.version = '0.3.4'
|
4
4
|
s.licenses = ['Apache-2.0']
|
5
5
|
s.summary = 'logstash output plugin for qingstor'
|
6
6
|
s.description = 'Collect the outputs of logstash and store into QingStor'
|
@@ -5,18 +5,18 @@ require 'logstash/outputs/qingstor/temporary_file'
|
|
5
5
|
require 'logstash/outputs/qingstor/rotation_policy'
|
6
6
|
|
7
7
|
describe LogStash::Outputs::Qingstor::RotationPolicy do
|
8
|
-
let(:
|
9
|
-
let(:
|
8
|
+
let(:file_size) { 5 }
|
9
|
+
let(:file_time) { 2 }
|
10
10
|
|
11
11
|
shared_examples 'size rotation' do
|
12
|
-
it 'raise error if
|
12
|
+
it 'raise error if file_size is no grater then 0' do
|
13
13
|
expect { described_class.new('size', 0, 0) }
|
14
14
|
.to raise_error(LogStash::ConfigurationError)
|
15
15
|
expect { described_class.new('size', -1, 0) }
|
16
16
|
.to raise_error(LogStash::ConfigurationError)
|
17
17
|
end
|
18
18
|
|
19
|
-
it "return true if the file has a bigger size value then '
|
19
|
+
it "return true if the file has a bigger size value then 'file_size'" do
|
20
20
|
file = double('file')
|
21
21
|
allow(file).to receive(:ctime) { Time.now }
|
22
22
|
allow(file).to receive(:empty?) { true }
|
@@ -34,7 +34,7 @@ describe LogStash::Outputs::Qingstor::RotationPolicy do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
shared_examples 'time rotation' do
|
37
|
-
it 'raise error if
|
37
|
+
it 'raise error if file_time is no grater then 0' do
|
38
38
|
expect { described_class.new('time', 0, 0) }
|
39
39
|
.to raise_error(LogStash::ConfigurationError)
|
40
40
|
expect { described_class.new('time', 0, -1) }
|
@@ -51,7 +51,7 @@ describe LogStash::Outputs::Qingstor::RotationPolicy do
|
|
51
51
|
|
52
52
|
it 'return false if the file is old enough with file size 0' do
|
53
53
|
file = double('file')
|
54
|
-
allow(file).to receive(:ctime) { Time.now - (
|
54
|
+
allow(file).to receive(:ctime) { Time.now - (file_time * 2 * 60) }
|
55
55
|
allow(file).to receive(:empty?) { true }
|
56
56
|
allow(file).to receive(:size) { 0 }
|
57
57
|
expect(subject.rotate?(file)).to be_falsey
|
@@ -59,7 +59,7 @@ describe LogStash::Outputs::Qingstor::RotationPolicy do
|
|
59
59
|
|
60
60
|
it 'return truth if the file is old enough and non-empty' do
|
61
61
|
file = double('file')
|
62
|
-
allow(file).to receive(:ctime) { Time.now - (
|
62
|
+
allow(file).to receive(:ctime) { Time.now - (file_time * 2 * 60) }
|
63
63
|
allow(file).to receive(:empty?) { false }
|
64
64
|
allow(file).to receive(:size) { 5 * 1024 * 1024 }
|
65
65
|
expect(subject.rotate?(file)).to be_truthy
|
@@ -67,21 +67,41 @@ describe LogStash::Outputs::Qingstor::RotationPolicy do
|
|
67
67
|
end
|
68
68
|
|
69
69
|
context 'when time policy' do
|
70
|
-
subject { described_class.new('time',
|
70
|
+
subject { described_class.new('time', file_size, file_time) }
|
71
71
|
|
72
72
|
include_examples 'time rotation'
|
73
|
+
|
74
|
+
it 'get suitable description of the class' do
|
75
|
+
time = file_time * 60
|
76
|
+
expect(subject.to_s).to eq({:policy=>"time",
|
77
|
+
:file_time=>time}.to_s)
|
78
|
+
end
|
73
79
|
end
|
74
80
|
|
75
81
|
context 'when size policy' do
|
76
|
-
subject { described_class.new('size',
|
82
|
+
subject { described_class.new('size', file_size, file_time) }
|
77
83
|
|
78
84
|
include_examples 'size rotation'
|
85
|
+
|
86
|
+
it 'get suitable description of the class' do
|
87
|
+
size = file_size * 1024 * 1024
|
88
|
+
expect(subject.to_s).to eq({:policy=>"size",
|
89
|
+
:file_size=>size}.to_s)
|
90
|
+
end
|
79
91
|
end
|
80
92
|
|
81
93
|
context 'when size_and_time policy' do
|
82
|
-
subject { described_class.new('size_and_time',
|
94
|
+
subject { described_class.new('size_and_time', file_size, file_time) }
|
83
95
|
|
84
96
|
include_examples 'time rotation'
|
85
97
|
include_examples 'size rotation'
|
98
|
+
|
99
|
+
it 'get suitable description of the class' do
|
100
|
+
size = file_size * 1024 * 1024
|
101
|
+
time = file_time * 60
|
102
|
+
expect(subject.to_s).to eq({:policy=>"sizeandtime",
|
103
|
+
:file_time=>time,
|
104
|
+
:file_size=>size}.to_s)
|
105
|
+
end
|
86
106
|
end
|
87
107
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logstash-output-qingstor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Zhao
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01
|
11
|
+
date: 2018-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|