fluent-plugin-ftp 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bae24cf10e0a1de9456803e8cfded0a8b8ff1ad6
4
+ data.tar.gz: e48fbb7ffbe75d03d69f76d5eb933a631f87ca9a
5
+ SHA512:
6
+ metadata.gz: 08c0a72cfa182122189e1bc0216659894dbbacb3edc44f59fdc7e53b29d1582f9a032a5a11d1c6f0430c25bf19484e2a3add3677df2ed069496dbebc805ed095
7
+ data.tar.gz: 7df1f757450443171330ce98d8f95f997bbf050e814cc38c93da4f604fa5679a2b2c467425fcda3955a43875553b05657fb506d32f80a972f7c8f7c13b10991a
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.2
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - rbx-19mode
8
+
9
+ branches:
10
+ only:
11
+ - master
12
+
13
+ script: bundle exec rake test
data/AUTHORS ADDED
@@ -0,0 +1 @@
1
+ Kazuki Ohta <kazuki.ohta _at_ gmail.com>
@@ -0,0 +1,4 @@
1
+ Release 0.1.1 - 2011/09/27
2
+
3
+ * First release
4
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,46 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ fluent-plugin-ftp (0.0.1)
5
+ aws-sdk (~> 1.8.2)
6
+ fluent-mixin-config-placeholders (~> 0.2.0)
7
+ fluentd (~> 0.10.0)
8
+ yajl-ruby (~> 1.0)
9
+
10
+ GEM
11
+ remote: http://rubygems.org/
12
+ specs:
13
+ aws-sdk (1.8.5)
14
+ json (~> 1.4)
15
+ nokogiri (>= 1.4.4)
16
+ uuidtools (~> 2.1)
17
+ cool.io (1.2.1)
18
+ flexmock (1.3.3)
19
+ fluent-mixin-config-placeholders (0.2.4)
20
+ fluentd
21
+ uuidtools
22
+ fluentd (0.10.44)
23
+ cool.io (>= 1.1.1, < 2.0.0, != 1.2.0)
24
+ http_parser.rb (~> 0.5.1)
25
+ json (>= 1.4.3)
26
+ msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
27
+ sigdump (~> 0.2.2)
28
+ yajl-ruby (~> 1.0)
29
+ http_parser.rb (0.5.3)
30
+ json (1.8.1)
31
+ mini_portile (0.5.2)
32
+ msgpack (0.5.8)
33
+ nokogiri (1.6.1)
34
+ mini_portile (~> 0.5.0)
35
+ rake (10.1.1)
36
+ sigdump (0.2.2)
37
+ uuidtools (2.1.4)
38
+ yajl-ruby (1.2.0)
39
+
40
+ PLATFORMS
41
+ ruby
42
+
43
+ DEPENDENCIES
44
+ flexmock (>= 1.2.0)
45
+ fluent-plugin-ftp!
46
+ rake (>= 0.9.2)
File without changes
@@ -0,0 +1,14 @@
1
+
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake/testtask'
6
+
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << 'lib' << 'test'
9
+ test.test_files = FileList['test/*.rb']
10
+ test.verbose = true
11
+ end
12
+
13
+ task :default => [:build]
14
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,24 @@
1
+ <source>
2
+ type forward
3
+ </source>
4
+
5
+ <match debug.**>
6
+ type copy
7
+ <store>
8
+ type stdout
9
+ </store>
10
+ <store>
11
+ type ftp
12
+ ftp_server localhost
13
+ ftp_user user
14
+ ftp_password pass
15
+ ftp_dir dir
16
+
17
+ buffer_path buffer_dir
18
+ flush_interval 3s
19
+
20
+ time_slice_format %Y%m%d%H
21
+ time_slice_wait 10m
22
+ utc
23
+ </store>
24
+ </match>
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-ftp"
6
+ gem.description = "FTP input / output plugin for Fluentd data collector"
7
+ gem.homepage = "https://github.com/kzk/fluent-plugin-ftp"
8
+ gem.summary = gem.description
9
+ gem.version = File.read("VERSION").strip
10
+ gem.authors = ["Kazuki Ohta"]
11
+ gem.email = "kazuki.ohta@gmail.com"
12
+ gem.has_rdoc = false
13
+ #gem.platform = Gem::Platform::RUBY
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ gem.require_paths = ['lib']
18
+
19
+ gem.add_dependency "fluentd", "~> 0.10.0"
20
+ gem.add_dependency "aws-sdk", "~> 1.8.2"
21
+ gem.add_dependency "yajl-ruby", "~> 1.0"
22
+ gem.add_dependency "fluent-mixin-config-placeholders", "~> 0.2.0"
23
+ gem.add_development_dependency "rake", ">= 0.9.2"
24
+ gem.add_development_dependency "flexmock", ">= 1.2.0"
25
+ end
@@ -0,0 +1,174 @@
1
+ module Fluent
2
+ require 'fluent/mixin/config_placeholders'
3
+
4
+ class FTPOutput < Fluent::TimeSlicedOutput
5
+ Fluent::Plugin.register_output('ftp', self)
6
+
7
+ def initialize
8
+ super
9
+ require 'net/ftp'
10
+ require 'zlib'
11
+ require 'time'
12
+ require 'tempfile'
13
+ require 'open3'
14
+ require 'pathname'
15
+ end
16
+
17
+ config_param :path, :string, :default => ""
18
+ config_param :time_format, :string, :default => nil
19
+
20
+ include SetTagKeyMixin
21
+ config_set_default :include_tag_key, false
22
+
23
+ include SetTimeKeyMixin
24
+ config_set_default :include_time_key, false
25
+
26
+ config_param :ftp_server, :string
27
+ config_param :ftp_user, :string
28
+ config_param :ftp_password, :string
29
+ config_param :ftp_dir, :string
30
+ config_param :ftp_file_name_format, :string, :default => "%{path}%{time_slice}_%{index}.%{file_extension}"
31
+ config_param :store_as, :string, :default => "gzip"
32
+
33
+ include Fluent::Mixin::ConfigPlaceholders
34
+
35
+ def placeholders
36
+ [:percent]
37
+ end
38
+
39
+ def configure(conf)
40
+ super
41
+
42
+ if format_json = conf['format_json']
43
+ @format_json = true
44
+ else
45
+ @format_json = false
46
+ end
47
+
48
+ @timef = TimeFormatter.new(@time_format, @localtime)
49
+
50
+ @ext = case @store_as
51
+ when 'gzip' then 'gz'
52
+ when 'lzo' then
53
+ begin
54
+ Open3.capture3('lzop -V')
55
+ rescue Errno::ENOENT
56
+ raise ConfigError, "'lzop' utility must be in PATH for LZO compression"
57
+ end
58
+ 'lzo'
59
+ when 'json' then 'json'
60
+ else 'txt'
61
+ end
62
+
63
+ if @localtime
64
+ @path_slicer = Proc.new { |path| Time.now.strftime(path) }
65
+ else
66
+ @path_slicer = Proc.new { |path| Time.now.utc.strftime(path) }
67
+ end
68
+ end
69
+
70
+ def start
71
+ super
72
+ with_ftp_connection { |conn|
73
+ # check valid connection here, nothing to do
74
+ }
75
+ end
76
+
77
+ def format(tag, time, record)
78
+ if @include_time_key || !@format_json
79
+ time_str = @timef.format(time)
80
+ end
81
+
82
+ # copied from each mixin because current TimeSlicedOutput can't support mixins.
83
+ if @include_tag_key
84
+ record[@tag_key] = tag
85
+ end
86
+ if @include_time_key
87
+ record[@time_key] = time_str
88
+ end
89
+
90
+ if @format_json
91
+ Yajl.dump(record) + "\n"
92
+ else
93
+ "#{time_str}\t#{tag}\t#{Yajl.dump(record)}\n"
94
+ end
95
+ end
96
+
97
+ def write(chunk)
98
+ with_ftp_connection { |conn|
99
+ ftp_filename = gen_ftp_filename(conn, chunk.key)
100
+ with_compression(@store_as, chunk) { |tmp_path|
101
+ conn.putbinaryfile(tmp_path, ftp_filename)
102
+ }
103
+ }
104
+ end
105
+
106
+ private
107
+
108
+ def with_ftp_connection
109
+ ftp = Net::FTP.new
110
+ ftp.binary = true
111
+ begin
112
+ ftp.connect(@ftp_server)
113
+ ftp.login(@ftp_user, @ftp_password)
114
+ ftp.chdir(@ftp_dir)
115
+ yield ftp
116
+ ensure
117
+ ftp.quit() rescue nil
118
+ end
119
+ end
120
+
121
+ def gen_ftp_filename(conn, chunk_key)
122
+ i = 0
123
+ begin
124
+ values_for_ftp_file_name = {
125
+ "path" => @path_slicer.call(@path),
126
+ "time_slice" => chunk_key,
127
+ "file_extension" => @ext,
128
+ "index" => i
129
+ }
130
+ ftp_file_name = @ftp_file_name_format.gsub(%r(%{[^}]+})) { |expr|
131
+ values_for_ftp_file_name[expr[2...expr.size-1]]
132
+ }
133
+ i += 1
134
+ end while ftp_file_exists?(conn, ftp_file_name)
135
+ return ftp_file_name
136
+ end
137
+
138
+ def ftp_file_exists?(conn, filename)
139
+ begin
140
+ not conn.nlst(filename).empty?
141
+ rescue Net::FTPTempError => e
142
+ err_code = e.message[0,3].to_i
143
+ return false if err_code == 450
144
+ raise e
145
+ end
146
+ end
147
+
148
+ def with_compression(codec, chunk)
149
+ tmp = Tempfile.new("ftp-")
150
+ begin
151
+ if codec == "gzip"
152
+ w = Zlib::GzipWriter.new(tmp)
153
+ chunk.write_to(w)
154
+ w.close
155
+ elsif codec == "lzo"
156
+ w = Tempfile.new("chunk-tmp")
157
+ chunk.write_to(w)
158
+ w.close
159
+ tmp.close
160
+ # we don't check the return code because we can't recover lzop failure.
161
+ system "lzop -qf1 -o #{tmp.path} #{w.path}"
162
+ else
163
+ chunk.write_to(tmp)
164
+ tmp.close
165
+ end
166
+ yield Pathname.new(tmp.path)
167
+ ensure
168
+ tmp.close(true) rescue nil
169
+ w.close rescue nil
170
+ w.unlink rescue nil
171
+ end
172
+ end
173
+ end
174
+ end
metadata ADDED
@@ -0,0 +1,137 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-ftp
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kazuki Ohta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-12 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.10.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.10.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.8.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.8.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: yajl-ruby
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fluent-mixin-config-placeholders
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.2.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.2.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 0.9.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 0.9.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: flexmock
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 1.2.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 1.2.0
97
+ description: FTP input / output plugin for Fluentd data collector
98
+ email: kazuki.ohta@gmail.com
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files: []
102
+ files:
103
+ - ".travis.yml"
104
+ - AUTHORS
105
+ - ChangeLog
106
+ - Gemfile
107
+ - Gemfile.lock
108
+ - README.md
109
+ - Rakefile
110
+ - VERSION
111
+ - example.conf
112
+ - fluent-plugin-ftp.gemspec
113
+ - lib/fluent/plugin/out_ftp.rb
114
+ homepage: https://github.com/kzk/fluent-plugin-ftp
115
+ licenses: []
116
+ metadata: {}
117
+ post_install_message:
118
+ rdoc_options: []
119
+ require_paths:
120
+ - lib
121
+ required_ruby_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ required_rubygems_version: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ requirements: []
132
+ rubyforge_project:
133
+ rubygems_version: 2.2.2
134
+ signing_key:
135
+ specification_version: 4
136
+ summary: FTP input / output plugin for Fluentd data collector
137
+ test_files: []