fluent-plugin-cat-sweep 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2c359caaffa952bd5d22a4e7a446bd817b9431c9
4
+ data.tar.gz: b21ad62093a0737d4d67fe2a4e760d85a6593c68
5
+ SHA512:
6
+ metadata.gz: 8bdd6442226a93d646122f4b2c42399b3fd2388e40b20f483830275b858256619123acdf6853b3e34d90ade69dcfe8714d2da16243b9e83a98d28f46bbc7bc23
7
+ data.tar.gz: d76f94192d97fcdfa559b0e66fec2efc6f3e68f97f79c5c89cf51190bd895807891430ccfe2207aa366e0cda5c1b95d60fd9074fb40859a23bbcd728d9c88d43
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ vendor
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.*
6
+ - 2.2.*
7
+ gemfile:
8
+ - Gemfile
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-cat-sweep.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 takahiro.nakayama
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # fluent-plugin-cat-sweep
2
+
3
+ [![Build Status](https://secure.travis-ci.org/civitaspo/fluent-plugin-cat-sweep.png?branch=master)](http://travis-ci.org/civitaspo/fluent-plugin-cat-sweep)
4
+
5
+ Fluentd plugin to read data from files and to remove or move after processing.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'fluent-plugin-cat-sweep'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install fluent-plugin-cat-sweep
22
+
23
+ ## Configuration
24
+
25
+ ```
26
+ <source>
27
+ type cat_sweep
28
+
29
+ # Required. process files that match this pattern using glob.
30
+ file_path_with_glob /tmp/test/file_*
31
+
32
+ # Input pattern. It depends on Parser plugin
33
+ format tsv
34
+ keys xpath,access_time,label,payload
35
+
36
+ # Required. process files that are older than this parameter(seconds).
37
+ # [WARNING!!]: this plugin move or remove files even if the files open,
38
+ # so this parameter is set as seconds that the application close files definitely.
39
+ waiting_seconds 60
40
+
41
+ # Optional. default is file.cat_sweep
42
+ tag test.input
43
+
44
+ # Optional. processing files is renamed with this suffix. default is .processing
45
+ processing_file_suffix .processing
46
+
47
+ # Optional. error files is renamed with this suffix. default is .error
48
+ error_file_suffix .err
49
+
50
+ # Optional. line terminater. default is "\n"
51
+ line_terminated_by ,
52
+
53
+ # Optional. max bytes oneline can has. default 536870912 (512MB)
54
+ oneline_max_bytes 128000
55
+
56
+ # Optional. processed files are move to this directory.
57
+ # default '/tmp'
58
+ move_to /tmp/test_processed
59
+
60
+ # Optional. this parameter indicated, `move_to` is ignored.
61
+ # files that is processed are removed.
62
+ # default is false.
63
+ remove_after_processing true
64
+
65
+ # Optional. default 5 seconds.
66
+ run_interval 10
67
+ </source>
68
+ ```
69
+
70
+ ## Contributing
71
+
72
+ 1. Fork it ( https://github.com/civitaspo/fluent-plugin-cat-sweep/fork )
73
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
74
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
75
+ 4. Push to the branch (`git push origin my-new-feature`)
76
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ desc 'Run test_unit based test'
5
+ Rake::TestTask.new(:test) do |t|
6
+ t.libs << "test"
7
+ t.test_files = Dir["test/**/test_*.rb"].sort
8
+ t.verbose = true
9
+ #t.warning = true
10
+ end
11
+ task :default => :test
12
+
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-cat-sweep"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Civitaspo(takahiro.nakayama)"]
9
+ spec.email = ["civitaspo@gmail.com"]
10
+
11
+ spec.summary = %q{Fluentd plugin to cat files and move them.}
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/civitaspo/fluent-plugin-cat-sweep"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split("\n")
17
+ spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "fluentd"
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "test-unit"
25
+ spec.add_development_dependency "test-unit-rr"
26
+ spec.add_development_dependency "pry"
27
+ spec.add_development_dependency "pry-nav"
28
+ end
@@ -0,0 +1,212 @@
1
+
2
+ module Fluent
3
+ class CatSweepInput < Input
4
+ Plugin.register_input('cat_sweep', self)
5
+
6
+ class OneLineMaxBytesOverError < StandardError
7
+ end
8
+
9
+ class FormatError < StandardError
10
+ end
11
+
12
+ config_param :file_path_with_glob, :string
13
+ config_param :format, :string
14
+ config_param :waiting_seconds, :integer # seconds
15
+ config_param :tag, :string, :default => 'file.cat_sweep'
16
+ config_param :processing_file_suffix, :string, :default => '.processing'
17
+ config_param :error_file_suffix, :string, :default => '.error'
18
+ config_param :line_terminated_by, :string, :default => "\n"
19
+ config_param :oneline_max_bytes, :integer, :default => 536870912 # 512MB
20
+ config_param :move_to, :string, :default => '/tmp'
21
+ config_param :remove_after_processing, :bool, :default => false
22
+ config_param :run_interval, :integer, :default => 5
23
+
24
+
25
+ # To support log_level option implemented by Fluentd v0.10.43
26
+ unless method_defined?(:log)
27
+ define_method("log") { $log }
28
+ end
29
+
30
+ # Define `router` method of v0.12 to support v0.10 or earlier
31
+ unless method_defined?(:router)
32
+ define_method("router") { Fluent::Engine }
33
+ end
34
+
35
+ def configure(conf)
36
+ super
37
+
38
+ @parser = Plugin.new_parser(@format)
39
+ @parser.configure(conf)
40
+
41
+ if @processing_file_suffix.empty?
42
+ raise Fluent::ConfigError, "in_cat_sweep: `processing_file_suffix` must has some letters."
43
+ end
44
+
45
+ if @error_file_suffix.empty?
46
+ raise Fluent::ConfigError, "in_cat_sweep: `error_file_suffix` must has some letters."
47
+ end
48
+
49
+ if @line_terminated_by.empty?
50
+ raise Fluent::ConfigError, "in_cat_sweep: `line_terminated_by` must has some letters."
51
+ end
52
+
53
+ if !remove_file? and !Dir.exists?(@move_to)
54
+ raise Fluent::ConfigError, "in_cat_sweep: `move_to` directory must be existed."
55
+ end
56
+
57
+ @read_bytes_once = 262144 # 256 KB
58
+
59
+ end
60
+
61
+ def start
62
+ @processing = true
63
+ @thread = Thread.new(&method(:run_periodic))
64
+ end
65
+
66
+ def shutdown
67
+ @processing = false
68
+ @thread.join
69
+ end
70
+
71
+ def run_periodic
72
+ while @processing
73
+ sleep @run_interval
74
+
75
+ Dir.glob(@file_path_with_glob).map do |filename|
76
+ next unless will_process?(filename)
77
+
78
+ processing_filename = get_processing_filename(filename)
79
+ begin
80
+ lock_with_renaming(filename, processing_filename) do
81
+ process(processing_filename)
82
+ after_processing(processing_filename)
83
+ end
84
+ rescue => e
85
+ log.error "in_cat_sweep: processing error: #{e}, file: #{processing_filename}",
86
+ :error => e, :error_class => e.class
87
+ log.error_backtrace
88
+ safe_fail(processing_filename)
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ private
95
+
96
+ def will_process?(filename)
97
+ !(processing?(filename) or error_file?(filename) or sufficient_waiting?(filename))
98
+ end
99
+
100
+ def processing?(filename)
101
+ filename.end_with?(@processing_file_suffix)
102
+ end
103
+
104
+ def error_file?(filename)
105
+ filename.end_with?(@error_file_suffix)
106
+ end
107
+
108
+ def sufficient_waiting?(filename)
109
+ (Time.now - File.mtime(filename)).to_i < @waiting_seconds
110
+ end
111
+
112
+ def get_processing_filename(filename)
113
+ tmpfile = String.new
114
+ tmpfile << filename << '.' << Process.pid.to_s << '.'
115
+ tmpfile << Time.now.to_i.to_s << '.' << @processing_file_suffix
116
+ end
117
+
118
+ def get_error_filename(filename)
119
+ errfile = String.new
120
+ errfile << filename << '.' << @error_file_suffix
121
+ end
122
+
123
+ def safe_fail(filename)
124
+ begin
125
+ lock_with_renaming(filename, get_error_filename(filename))
126
+ rescue => e
127
+ log.error "in_cat_sweep: rename #{filename} to error name. message: #{e}",
128
+ :error => e, :error_class => e.class
129
+ log.error_backtrace
130
+ end
131
+ end
132
+
133
+ def buffer_clean!
134
+ @buffer = String.new.force_encoding('ASCII-8BIT')
135
+ end
136
+
137
+ def buffer
138
+ @buffer || buffer_clean!
139
+ end
140
+
141
+ def remove_file?
142
+ @remove_after_processing
143
+ end
144
+
145
+ def read_each_line(io)
146
+ buffer_clean!
147
+
148
+ io.each(@line_terminated_by, @read_bytes_once) do |like_line|
149
+ buffer << like_line
150
+
151
+ if buffer.length > @oneline_max_bytes
152
+ begin
153
+ raise OneLineMaxBytesOverError,
154
+ "in_cat_sweep: buffer length is over #{@oneline_max_bytes} bytes. remove: #{buffer}"
155
+ ensure
156
+ buffer_clean!
157
+ end
158
+ end
159
+
160
+ if buffer.end_with?(@line_terminated_by)
161
+ yield(buffer.chomp!(@line_terminated_by))
162
+ buffer_clean!
163
+ end
164
+ end
165
+ yield(buffer.chomp!(@line_terminated_by))
166
+ buffer_clean!
167
+ end
168
+
169
+ def emit_message(message)
170
+ if message
171
+ @parser.parse(message) do |time, record|
172
+ unless time and record
173
+ raise FormatError,
174
+ "in_cat_sweep: pattern not match: #{message.inspect}"
175
+ end
176
+ router.emit(@tag, time, record)
177
+ end
178
+ end
179
+ end
180
+
181
+ def process(filename)
182
+ File.open(filename, 'r') do |tfile|
183
+ read_each_line(tfile) do |line|
184
+ emit_message(line)
185
+ end
186
+ end
187
+ end
188
+
189
+ def lock_with_renaming(filename_from, filename_to)
190
+ file = File.open(filename_from)
191
+ begin
192
+ if file.flock(File::LOCK_EX | File::LOCK_NB)
193
+ File.rename(filename_from, filename_to)
194
+ yield if block_given?
195
+ else
196
+ log.warn "in_cat_sweep: lock failed: skip #{filename_from}"
197
+ end
198
+ ensure
199
+ file.flock(File::LOCK_UN) # release the lock
200
+ file.close
201
+ end
202
+ end
203
+
204
+ def after_processing(filename)
205
+ if remove_file?
206
+ FileUtils.rm(filename)
207
+ else
208
+ FileUtils.mv(filename, @move_to)
209
+ end
210
+ end
211
+ end
212
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,8 @@
1
+ require 'test/unit'
2
+ require 'fluent/log'
3
+ require 'fluent/test'
4
+
5
+ unless defined?(Test::Unit::AssertionFailedError)
6
+ class Test::Unit::AssertionFailedError < StandardError
7
+ end
8
+ end
@@ -0,0 +1,158 @@
1
+ require_relative 'helper'
2
+ require 'rr'
3
+ require 'fluent/plugin/in_cat_sweep'
4
+
5
+ class CatSweepInputTest < Test::Unit::TestCase
6
+ def setup
7
+ Fluent::Test.setup
8
+ FileUtils.mkdir_p(TMP_DIR_FROM)
9
+ FileUtils.mkdir_p(TMP_DIR_TO)
10
+ end
11
+
12
+ def teardown
13
+ FileUtils.rm_r(TMP_DIR_FROM)
14
+ FileUtils.rm_r(TMP_DIR_TO)
15
+ end
16
+
17
+ TMP_DIR_FROM = '/tmp/fluent_plugin_test_in_cat_sweep_from'
18
+ TMP_DIR_TO = '/tmp/fluent_plugin_test_in_cat_sweep_to'
19
+
20
+ CONFIG_BASE = %[
21
+ file_path_with_glob #{TMP_DIR_FROM}/*
22
+ ]
23
+
24
+ def create_driver(conf, use_v1 = true)
25
+ Fluent::Test::InputTestDriver.new(Fluent::CatSweepInput).configure(conf, use_v1)
26
+ end
27
+
28
+ def test_required_configure
29
+ assert_raise(Fluent::ConfigError) do
30
+ d = create_driver(%[])
31
+ end
32
+
33
+ assert_raise(Fluent::ConfigError) do
34
+ d = create_driver(CONFIG_BASE)
35
+ end
36
+
37
+ assert_raise(Fluent::ConfigError) do
38
+ d = create_driver(CONFIG_BASE + %[format tsv])
39
+ end
40
+
41
+ d = create_driver(CONFIG_BASE + %[
42
+ format tsv
43
+ waiting_seconds 5
44
+ ])
45
+
46
+ assert_equal "#{TMP_DIR_FROM}/*", d.instance.instance_variable_get(:@file_path_with_glob)
47
+ assert_equal 'tsv', d.instance.instance_variable_get(:@format)
48
+ assert_equal 5, d.instance.instance_variable_get(:@waiting_seconds)
49
+ end
50
+
51
+ def compare_test_result(emits, tests)
52
+ emits.each_index do |i|
53
+ assert_equal(tests[i]['expected'], emits[i][2]['message'])
54
+ end
55
+ end
56
+
57
+ TEST_CASES =
58
+ {
59
+ 'none' => [
60
+ {'msg' => "tcptest1\n", 'expected' => 'tcptest1'},
61
+ {'msg' => "tcptest2\n", 'expected' => 'tcptest2'},
62
+ ],
63
+ 'tsv' => [
64
+ {'msg' => "t.e.s.t.1\t12345\ttcptest1\t{\"json\":1}\n", 'expected' => '{"json":1}'},
65
+ {'msg' => "t.e.s.t.2\t54321\ttcptest2\t{\"json\":\"char\"}\n", 'expected' => '{"json":"char"}'},
66
+ ],
67
+ 'json' => [
68
+ {'msg' => {'k' => 123, 'message' => 'tcptest1'}.to_json + "\n", 'expected' => 'tcptest1'},
69
+ {'msg' => {'k' => 'tcptest2', 'message' => 456}.to_json + "\n", 'expected' => 456},
70
+ ]
71
+ }
72
+
73
+ TEST_CASES.each do |format, test_cases|
74
+ test_case_name = "test_msg_process_#{format}"
75
+ define_method(test_case_name) do
76
+ File.open("#{TMP_DIR_FROM}/#{test_case_name}", 'w') do |io|
77
+ test_cases.each do |test|
78
+ io.write(test['msg'])
79
+ end
80
+ end
81
+
82
+ d = create_driver(CONFIG_BASE + %[
83
+ format #{format}
84
+ waiting_seconds 0
85
+ keys hdfs_path,unixtimestamp,label,message
86
+ ])
87
+ d.run
88
+
89
+ compare_test_result(d.emits, test_cases)
90
+ assert(Dir.glob("#{TMP_DIR_FROM}/#{test_case_name}*").empty?)
91
+ end
92
+ end
93
+
94
+ def test_move_file
95
+ format = 'tsv'
96
+ test_cases =
97
+ [
98
+ {'msg' => "t.e.s.t.1\t12345\ttcptest1\t{\"json\":1}\n", 'expected' => '{"json":1}'},
99
+ {'msg' => "t.e.s.t.2\t54321\ttcptest2\t{\"json\":\"char\"}\n", 'expected' => '{"json":"char"}'},
100
+ ]
101
+
102
+ File.open("#{TMP_DIR_FROM}/test_move_file", 'w') do |io|
103
+ test_cases.each do |test|
104
+ io.write(test['msg'])
105
+ end
106
+ end
107
+
108
+ d = create_driver(CONFIG_BASE + %[
109
+ format #{format}
110
+ waiting_seconds 0
111
+ keys hdfs_path,unixtimestamp,label,message
112
+ move_to #{TMP_DIR_TO}
113
+ ])
114
+ d.run
115
+
116
+ compare_test_result(d.emits, test_cases)
117
+
118
+ assert(Dir.glob("#{TMP_DIR_FROM}/test_move_file*").empty?)
119
+ assert_match(
120
+ %r{\A#{TMP_DIR_TO}/test_move_file.*\.processing},
121
+ Dir.glob("#{TMP_DIR_TO}/test_move_file*").first)
122
+ assert_equal(
123
+ test_cases.map{|t|t['msg']}.join.to_s,
124
+ File.read(Dir.glob("#{TMP_DIR_TO}/test_move_file*").first))
125
+ end
126
+
127
+ def test_oneline_max_bytes
128
+ format = 'tsv'
129
+ test_cases =
130
+ [
131
+ {'msg' => "t.e.s.t.1\t12345\ttcptest1\t{\"json\":1}\n", 'expected' => '{"json":1}'},
132
+ {'msg' => "t.e.s.t.2\t54321\ttcptest2\t{\"json\":\"char\"}\n", 'expected' => '{"json":"char"}'},
133
+ ]
134
+
135
+ File.open("#{TMP_DIR_FROM}/test_oneline_max_bytes", 'w') do |io|
136
+ test_cases.each do |test|
137
+ io.write(test['msg'])
138
+ end
139
+ end
140
+
141
+ d = create_driver(CONFIG_BASE + %[
142
+ format #{format}
143
+ waiting_seconds 0
144
+ keys hdfs_path,unixtimestamp,label,message
145
+ move_to #{TMP_DIR_TO}
146
+ oneline_max_bytes 1
147
+ ])
148
+
149
+ d.run
150
+
151
+ assert_match(
152
+ %r{\A#{TMP_DIR_FROM}/test_oneline_max_bytes.*\.error},
153
+ Dir.glob("#{TMP_DIR_FROM}/test_oneline_max_bytes*").first)
154
+ assert_equal(
155
+ test_cases.map{|t|t['msg']}.join.to_s,
156
+ File.read(Dir.glob("#{TMP_DIR_FROM}/test_oneline_max_bytes*.error").first))
157
+ end
158
+ end
metadata ADDED
@@ -0,0 +1,155 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-cat-sweep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Civitaspo(takahiro.nakayama)
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit-rr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry-nav
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Fluentd plugin to cat files and move them.
112
+ email:
113
+ - civitaspo@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".travis.yml"
120
+ - CODE_OF_CONDUCT.md
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - fluent-plugin-cat-sweep.gemspec
126
+ - lib/fluent/plugin/in_cat_sweep.rb
127
+ - test/helper.rb
128
+ - test/test_in_cat_sweep.rb
129
+ homepage: https://github.com/civitaspo/fluent-plugin-cat-sweep
130
+ licenses:
131
+ - MIT
132
+ metadata: {}
133
+ post_install_message:
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubyforge_project:
149
+ rubygems_version: 2.4.5
150
+ signing_key:
151
+ specification_version: 4
152
+ summary: Fluentd plugin to cat files and move them.
153
+ test_files:
154
+ - test/helper.rb
155
+ - test/test_in_cat_sweep.rb