fluent-plugin-ftp 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []