logstash-output-swift 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2 -0
  3. data/CONTRIBUTORS +22 -0
  4. data/DEVELOPER.md +15 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE +201 -0
  7. data/NOTICE.TXT +2 -0
  8. data/README.md +38 -0
  9. data/lib/logstash/outputs/swift.rb +360 -0
  10. data/lib/logstash/outputs/swift/file_repository.rb +121 -0
  11. data/lib/logstash/outputs/swift/path_validator.rb +18 -0
  12. data/lib/logstash/outputs/swift/size_and_time_rotation_policy.rb +24 -0
  13. data/lib/logstash/outputs/swift/size_rotation_policy.rb +26 -0
  14. data/lib/logstash/outputs/swift/temporary_file.rb +71 -0
  15. data/lib/logstash/outputs/swift/temporary_file_factory.rb +129 -0
  16. data/lib/logstash/outputs/swift/time_rotation_policy.rb +26 -0
  17. data/lib/logstash/outputs/swift/uploader.rb +64 -0
  18. data/lib/logstash/outputs/swift/writable_directory_validator.rb +17 -0
  19. data/lib/logstash/outputs/swift/write_container_permission_validator.rb +52 -0
  20. data/logstash-output-swift.gemspec +28 -0
  21. data/spec/integration/dynamic_prefix_spec.rb +92 -0
  22. data/spec/integration/gzip_file_spec.rb +62 -0
  23. data/spec/integration/gzip_size_rotation_spec.rb +63 -0
  24. data/spec/integration/restore_from_crash_spec.rb +39 -0
  25. data/spec/integration/size_rotation_spec.rb +59 -0
  26. data/spec/integration/stress_test_spec.rb +60 -0
  27. data/spec/integration/time_based_rotation_with_constant_write_spec.rb +60 -0
  28. data/spec/integration/time_based_rotation_with_stale_write_spec.rb +64 -0
  29. data/spec/integration/upload_current_file_on_shutdown_spec.rb +51 -0
  30. data/spec/outputs/swift/file_repository_spec.rb +143 -0
  31. data/spec/outputs/swift/size_and_time_rotation_policy_spec.rb +77 -0
  32. data/spec/outputs/swift/size_rotation_policy_spec.rb +41 -0
  33. data/spec/outputs/swift/temporary_file_factory_spec.rb +89 -0
  34. data/spec/outputs/swift/temporary_file_spec.rb +47 -0
  35. data/spec/outputs/swift/time_rotation_policy_spec.rb +60 -0
  36. data/spec/outputs/swift/uploader_spec.rb +49 -0
  37. data/spec/outputs/swift/writable_directory_validator_spec.rb +40 -0
  38. data/spec/outputs/swift/write_container_permission_validator_spec.rb +38 -0
  39. data/spec/outputs/swift_spec.rb +76 -0
  40. data/spec/spec_helper.rb +48 -0
  41. data/spec/supports/helpers.rb +38 -0
  42. metadata +212 -0
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/temporary_file"
4
+ require "stud/temporary"
5
+ require "fileutils"
6
+ require "securerandom"
7
+
8
+ describe LogStash::Outputs::Swift::TemporaryFile do
9
+ let(:content) { "hello world" }
10
+ let(:key) { "foo" }
11
+ let(:uuid) { SecureRandom.uuid }
12
+ let(:temporary_file) { ::File.open(::File.join(temporary_directory, uuid, key), "w+") }
13
+ let(:temporary_directory) { Stud::Temporary.directory }
14
+
15
+ before :each do
16
+ FileUtils.mkdir_p(::File.join(temporary_directory, uuid))
17
+ end
18
+
19
+ subject { described_class.new(key, temporary_file, temporary_directory) }
20
+
21
+ it "returns the key of the file" do
22
+ expect(subject.key).to eq(key)
23
+ end
24
+
25
+ it "saves content to a file" do
26
+ subject.write(content)
27
+ subject.close
28
+ expect(File.read(subject.path).strip).to eq(content)
29
+ end
30
+
31
+ it "deletes a file" do
32
+ expect(File.exist?(subject.path)).to be_truthy
33
+ subject.delete!
34
+ expect(File.exist?(subject.path)).to be_falsey
35
+ end
36
+
37
+ it "successfully delete a file already closed" do
38
+ subject.close
39
+ expect(File.exist?(subject.path)).to be_truthy
40
+ subject.delete!
41
+ expect(File.exist?(subject.path)).to be_falsey
42
+ end
43
+
44
+ it "returns the creation time" do
45
+ expect(subject.ctime).to be < Time.now + 0.5
46
+ end
47
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/time_rotation_policy"
4
+ require "logstash/outputs/swift/temporary_file"
5
+
6
+ describe LogStash::Outputs::Swift::TimeRotationPolicy do
7
+ subject { described_class.new(max_time) }
8
+
9
+ let(:max_time) { 1 }
10
+ let(:temporary_directory) { Stud::Temporary.directory }
11
+ let(:temporary_file) { Stud::Temporary.file }
12
+ let(:name) { "foobar" }
13
+ let(:content) { "hello" * 1000 }
14
+ let(:file) { LogStash::Outputs::Swift::TemporaryFile.new(name, temporary_file, temporary_directory) }
15
+
16
+ it "raises an exception if the `file_time` is set to 0" do
17
+ expect { described_class.new(0) }.to raise_error(LogStash::ConfigurationError, /`time_file` need to be greather than 0/)
18
+ end
19
+
20
+ it "raises an exception if the `file_time` is < 0" do
21
+ expect { described_class.new(-100) }.to raise_error(LogStash::ConfigurationError, /`time_file` need to be greather than 0/)
22
+ end
23
+
24
+ context "when the size of the file is superior to 0" do
25
+ before :each do
26
+ file.write(content)
27
+ file.fsync
28
+ end
29
+
30
+ it "returns true if the file old enough" do
31
+ allow(file).to receive(:ctime).and_return(Time.now - (max_time * 2 * 60))
32
+ expect(subject.rotate?(file)).to be_truthy
33
+ end
34
+
35
+ it "returns false is not old enough" do
36
+ expect(subject.rotate?(file)).to be_falsey
37
+ end
38
+ end
39
+
40
+ context "When the size of the file is 0" do
41
+ it "returns false if the file old enough" do
42
+ allow(file).to receive(:ctime).and_return(Time.now - (max_time * 2 * 60))
43
+ expect(subject.rotate?(file)).to be_falsey
44
+ end
45
+
46
+ it "returns false is not old enough" do
47
+ expect(subject.rotate?(file)).to be_falsey
48
+ end
49
+ end
50
+
51
+ context "#needs_periodic?" do
52
+ it "return false" do
53
+ expect(subject.needs_periodic?).to be_truthy
54
+ end
55
+ end
56
+
57
+ it "convert minute into seconds" do
58
+ expect(subject.time_file).to eq(60)
59
+ end
60
+ end
@@ -0,0 +1,49 @@
1
+ # Encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/uploader"
4
+ require "logstash/outputs/swift/temporary_file"
5
+ require "fog/openstack"
6
+ require "stud/temporary"
7
+
8
+ describe LogStash::Outputs::Swift::Uploader do
9
+ let(:logger) { spy(:logger ) }
10
+ let(:max_upload_workers) { 1 }
11
+ let(:bucket_name) { "foobar-bucket" }
12
+
13
+ let(:service) { Fog::Storage::OpenStack.new }
14
+ let(:container) { service.directories.get(bucket_name) }
15
+
16
+ let(:temporary_directory) { Stud::Temporary.pathname }
17
+ let(:temporary_file) { Stud::Temporary.file }
18
+ let(:key) { "foobar" }
19
+ let(:upload_options) { {} }
20
+ let(:threadpool) do
21
+ Concurrent::ThreadPoolExecutor.new({
22
+ :min_threads => 1,
23
+ :max_threads => 8,
24
+ :max_queue => 1,
25
+ :fallback_policy => :caller_runs
26
+ })
27
+ end
28
+
29
+ let(:file) do
30
+ f = LogStash::Outputs::Swift::TemporaryFile.new(key, temporary_file, temporary_directory)
31
+ f.write("random content")
32
+ f.fsync
33
+ f
34
+ end
35
+
36
+ subject { described_class.new(container, logger, threadpool) }
37
+
38
+ it "upload file to the swift container" do
39
+ expect { subject.upload(file) }.not_to raise_error
40
+ end
41
+
42
+ it "execute a callback when the upload is complete" do
43
+ callback = proc { |f| }
44
+
45
+ expect(callback).to receive(:call).with(file)
46
+ subject.upload(file, { :on_complete => callback })
47
+ end
48
+
49
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/writable_directory_validator"
4
+ require "stud/temporary"
5
+
6
+ describe LogStash::Outputs::Swift::WritableDirectoryValidator do
7
+ let(:temporary_directory) { File.join(Stud::Temporary.directory, Time.now.to_i.to_s) }
8
+
9
+ subject { described_class }
10
+
11
+ context "when the directory doesn't exists" do
12
+ it "creates the directory" do
13
+ expect(Dir.exist?(temporary_directory)).to be_falsey
14
+ expect(subject.valid?(temporary_directory)).to be_truthy
15
+ expect(Dir.exist?(temporary_directory)).to be_truthy
16
+ end
17
+ end
18
+
19
+ context "when the directory exist" do
20
+ before do
21
+ FileUtils.mkdir_p(temporary_directory)
22
+ end
23
+
24
+ it "doesn't change the directory" do
25
+ expect(Dir.exist?(temporary_directory)).to be_truthy
26
+ expect(subject.valid?(temporary_directory)).to be_truthy
27
+ expect(Dir.exist?(temporary_directory)).to be_truthy
28
+ end
29
+ end
30
+
31
+ it "return false if the directory is not writable" do
32
+ expect(::File).to receive(:writable?).with(temporary_directory).and_return(false)
33
+ expect(subject.valid?(temporary_directory)).to be_falsey
34
+ end
35
+
36
+ it "return true if the directory is writable" do
37
+ expect(::File).to receive(:writable?).with(temporary_directory).and_return(true)
38
+ expect(subject.valid?(temporary_directory)).to be_truthy
39
+ end
40
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/swift/write_container_permission_validator"
4
+ require "fog/openstack"
5
+
6
+ describe LogStash::Outputs::Swift::WriteContainerPermissionValidator do
7
+ let(:logger) { spy(:logger ) }
8
+ let(:bucket_name) { "foobar" }
9
+ let(:obj) { double("swift_object") }
10
+
11
+ let(:service) { Fog::Storage::OpenStack.new }
12
+ let(:container) { service.directories.get(bucket_name) }
13
+
14
+ let(:upload_options) { {} }
15
+
16
+ subject { described_class.new(logger) }
17
+
18
+ context "when permissions are sufficient" do
19
+ it "returns true" do
20
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_return(obj)
21
+ expect(obj).to receive(:delete).and_return(true)
22
+ expect(subject.valid?(container)).to be_truthy
23
+ end
24
+
25
+ it "hides delete errors" do
26
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_return(obj)
27
+ expect(obj).to receive(:delete).and_raise(StandardError)
28
+ expect(subject.valid?(container)).to be_truthy
29
+ end
30
+ end
31
+
32
+ context "when permission aren't sufficient" do
33
+ it "returns false" do
34
+ expect(container).to receive_message_chain(:files, :create).with(any_args).and_raise(StandardError)
35
+ expect(subject.valid?(container)).to be_falsey
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,76 @@
1
+ # encoding: utf-8
2
+ require "logstash/outputs/swift"
3
+ require "logstash/event"
4
+ require "logstash/codecs/line"
5
+ require "stud/temporary"
6
+ require "fog/openstack"
7
+
8
+ describe LogStash::Outputs::Swift do
9
+ let(:prefix) { "super/%{server}" }
10
+ let(:bucket_name) { "mybucket" }
11
+ let(:options) { { "container" => bucket_name,
12
+ "prefix" => prefix,
13
+ "restore" => false,
14
+ "username" => "access_key_id",
15
+ "api_key" => "secret_access_key",
16
+ "auth_url" => "secret_access_key",
17
+ "project_name" => "secret_access_key",
18
+ "domain_name" => "secret_access_key"
19
+ } }
20
+ let(:service) { Fog::Storage::OpenStack.new }
21
+ let(:mock_container) { service.directories.get(bucket_name) }
22
+ let(:event) { LogStash::Event.new({ "server" => "overwatch" }) }
23
+ let(:event_encoded) { "super hype" }
24
+ let(:events_and_encoded) { { event => event_encoded } }
25
+
26
+ subject { described_class.new(options) }
27
+
28
+ before do
29
+ allow(subject).to receive(:container_resource).and_return(mock_container)
30
+ allow_any_instance_of(LogStash::Outputs::Swift::WriteContainerPermissionValidator).to receive(:valid?).with(mock_container).and_return(true)
31
+ end
32
+
33
+ context "#register configuration validation" do
34
+ describe "temporary directory" do
35
+ let(:temporary_directory) { Stud::Temporary.pathname }
36
+ let(:options) { super.merge({ "temporary_directory" => temporary_directory }) }
37
+
38
+ it "creates the directory when it doesn't exist" do
39
+ expect(Dir.exist?(temporary_directory)).to be_falsey
40
+ subject.register
41
+ expect(Dir.exist?(temporary_directory)).to be_truthy
42
+ end
43
+
44
+ it "raises an error if we cannot write to the directory" do
45
+ expect(LogStash::Outputs::Swift::WritableDirectoryValidator).to receive(:valid?).with(temporary_directory).and_return(false)
46
+ expect { subject.register }.to raise_error(LogStash::ConfigurationError)
47
+ end
48
+ end
49
+
50
+ it "validates the prefix" do
51
+ swift = described_class.new(options.merge({ "prefix" => "`no\><^" }))
52
+ expect { swift.register }.to raise_error(LogStash::ConfigurationError)
53
+ end
54
+
55
+ it "allow to not validate credentials" do
56
+ swift = described_class.new(options.merge({"validate_credentials_on_root_bucket" => false}))
57
+ expect_any_instance_of(LogStash::Outputs::Swift::WriteContainerPermissionValidator).not_to receive(:valid?).with(any_args)
58
+ swift.register
59
+ end
60
+ end
61
+
62
+ context "receiving events" do
63
+ before do
64
+ subject.register
65
+ end
66
+
67
+ after do
68
+ subject.close
69
+ end
70
+
71
+ it "uses `Event#sprintf` for the prefix" do
72
+ expect(event).to receive(:sprintf).with(prefix).and_return("super/overwatch")
73
+ subject.multi_receive_encoded(events_and_encoded)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,48 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require_relative "supports/helpers"
4
+ require "logstash/logging/logger"
5
+ require "fog/openstack"
6
+
7
+ LogStash::Logging::Logger::configure_logging("debug") if ENV["DEBUG"]
8
+
9
+ module Fog
10
+ module Storage
11
+ class OpenStack
12
+
13
+ class Mock
14
+
15
+ def put_object(container, object, data, options = {}, &block)
16
+ response = Excon::Response.new
17
+ response.status = 201
18
+ response.body = ""
19
+ response
20
+ end
21
+
22
+ def put_container(name, options = {})
23
+ response = Excon::Response.new
24
+ response.status = 201
25
+ response.body = ""
26
+ response
27
+ end
28
+
29
+ def get_container(container, options = {})
30
+ response = Excon::Response.new
31
+ response.status = 201
32
+ response.body = []
33
+ response
34
+ end
35
+
36
+ def get_containers(options = {})
37
+ response = Excon::Response.new
38
+ response.status = 201
39
+ response.body = []
40
+ response
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+
48
+ Fog.mock!
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ shared_context "setup plugin" do
3
+ let(:temporary_directory) { Stud::Temporary.pathname }
4
+
5
+ let(:bucket) { ENV["AWS_LOGSTASH_TEST_BUCKET"] }
6
+ let(:access_key_id) { ENV["AWS_ACCESS_KEY_ID"] }
7
+ let(:secret_access_key) { ENV["AWS_SECRET_ACCESS_KEY"] }
8
+ let(:size_file) { 100 }
9
+ let(:time_file) { 100 }
10
+ let(:tags) { [] }
11
+ let(:prefix) { "home" }
12
+ let(:region) { ENV['AWS_REGION'] }
13
+
14
+ let(:main_options) do
15
+ {
16
+ "bucket" => bucket,
17
+ "prefix" => prefix,
18
+ "temporary_directory" => temporary_directory,
19
+ "access_key_id" => access_key_id,
20
+ "secret_access_key" => secret_access_key,
21
+ "size_file" => size_file,
22
+ "time_file" => time_file,
23
+ "region" => region,
24
+ "tags" => []
25
+ }
26
+ end
27
+
28
+ let(:client_credentials) { Aws::Credentials.new(access_key_id, secret_access_key) }
29
+ let(:bucket_resource) { Aws::S3::Bucket.new(bucket, { :credentials => client_credentials, :region => region }) }
30
+
31
+ subject { LogStash::Outputs::S3.new(options) }
32
+ end
33
+
34
+ def clean_remote_files(prefix = "")
35
+ bucket_resource.objects(:prefix => prefix).each do |object|
36
+ object.delete
37
+ end
38
+ end
metadata ADDED
@@ -0,0 +1,212 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: logstash-output-swift
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.1'
5
+ platform: ruby
6
+ authors:
7
+ - kakoni
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-12-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: logstash-core-plugin-api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.60'
20
+ - - "<="
21
+ - !ruby/object:Gem::Version
22
+ version: '2.99'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '1.60'
30
+ - - "<="
31
+ - !ruby/object:Gem::Version
32
+ version: '2.99'
33
+ - !ruby/object:Gem::Dependency
34
+ name: fog-openstack
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: concurrent-ruby
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: stud
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.0.22
68
+ type: :runtime
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.0.22
75
+ - !ruby/object:Gem::Dependency
76
+ name: logstash-devutils
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: logstash-input-generator
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: logstash-codec-line
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ description: This gem is a Logstash plugin required to be installed on top of the
118
+ Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This
119
+ gem is not a stand-alone program
120
+ email: kakoni@gmail.com
121
+ executables: []
122
+ extensions: []
123
+ extra_rdoc_files: []
124
+ files:
125
+ - CHANGELOG.md
126
+ - CONTRIBUTORS
127
+ - DEVELOPER.md
128
+ - Gemfile
129
+ - LICENSE
130
+ - NOTICE.TXT
131
+ - README.md
132
+ - lib/logstash/outputs/swift.rb
133
+ - lib/logstash/outputs/swift/file_repository.rb
134
+ - lib/logstash/outputs/swift/path_validator.rb
135
+ - lib/logstash/outputs/swift/size_and_time_rotation_policy.rb
136
+ - lib/logstash/outputs/swift/size_rotation_policy.rb
137
+ - lib/logstash/outputs/swift/temporary_file.rb
138
+ - lib/logstash/outputs/swift/temporary_file_factory.rb
139
+ - lib/logstash/outputs/swift/time_rotation_policy.rb
140
+ - lib/logstash/outputs/swift/uploader.rb
141
+ - lib/logstash/outputs/swift/writable_directory_validator.rb
142
+ - lib/logstash/outputs/swift/write_container_permission_validator.rb
143
+ - logstash-output-swift.gemspec
144
+ - spec/integration/dynamic_prefix_spec.rb
145
+ - spec/integration/gzip_file_spec.rb
146
+ - spec/integration/gzip_size_rotation_spec.rb
147
+ - spec/integration/restore_from_crash_spec.rb
148
+ - spec/integration/size_rotation_spec.rb
149
+ - spec/integration/stress_test_spec.rb
150
+ - spec/integration/time_based_rotation_with_constant_write_spec.rb
151
+ - spec/integration/time_based_rotation_with_stale_write_spec.rb
152
+ - spec/integration/upload_current_file_on_shutdown_spec.rb
153
+ - spec/outputs/swift/file_repository_spec.rb
154
+ - spec/outputs/swift/size_and_time_rotation_policy_spec.rb
155
+ - spec/outputs/swift/size_rotation_policy_spec.rb
156
+ - spec/outputs/swift/temporary_file_factory_spec.rb
157
+ - spec/outputs/swift/temporary_file_spec.rb
158
+ - spec/outputs/swift/time_rotation_policy_spec.rb
159
+ - spec/outputs/swift/uploader_spec.rb
160
+ - spec/outputs/swift/writable_directory_validator_spec.rb
161
+ - spec/outputs/swift/write_container_permission_validator_spec.rb
162
+ - spec/outputs/swift_spec.rb
163
+ - spec/spec_helper.rb
164
+ - spec/supports/helpers.rb
165
+ homepage:
166
+ licenses:
167
+ - Apache-2.0
168
+ metadata:
169
+ logstash_plugin: 'true'
170
+ logstash_group: output
171
+ post_install_message:
172
+ rdoc_options: []
173
+ require_paths:
174
+ - lib
175
+ required_ruby_version: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - ">="
178
+ - !ruby/object:Gem::Version
179
+ version: '0'
180
+ required_rubygems_version: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - ">="
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ requirements: []
186
+ rubyforge_project:
187
+ rubygems_version: 2.6.13
188
+ signing_key:
189
+ specification_version: 4
190
+ summary: Sends Logstash events to the Openstack Swift Service
191
+ test_files:
192
+ - spec/integration/dynamic_prefix_spec.rb
193
+ - spec/integration/gzip_file_spec.rb
194
+ - spec/integration/gzip_size_rotation_spec.rb
195
+ - spec/integration/restore_from_crash_spec.rb
196
+ - spec/integration/size_rotation_spec.rb
197
+ - spec/integration/stress_test_spec.rb
198
+ - spec/integration/time_based_rotation_with_constant_write_spec.rb
199
+ - spec/integration/time_based_rotation_with_stale_write_spec.rb
200
+ - spec/integration/upload_current_file_on_shutdown_spec.rb
201
+ - spec/outputs/swift/file_repository_spec.rb
202
+ - spec/outputs/swift/size_and_time_rotation_policy_spec.rb
203
+ - spec/outputs/swift/size_rotation_policy_spec.rb
204
+ - spec/outputs/swift/temporary_file_factory_spec.rb
205
+ - spec/outputs/swift/temporary_file_spec.rb
206
+ - spec/outputs/swift/time_rotation_policy_spec.rb
207
+ - spec/outputs/swift/uploader_spec.rb
208
+ - spec/outputs/swift/writable_directory_validator_spec.rb
209
+ - spec/outputs/swift/write_container_permission_validator_spec.rb
210
+ - spec/outputs/swift_spec.rb
211
+ - spec/spec_helper.rb
212
+ - spec/supports/helpers.rb