fluent-plugin-mail 0.1.2 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c0ed5964e665422a987c3698d6689c521cb05ae
4
- data.tar.gz: c44f585a3b06b52381b74c96cc2a2a835a8ed26c
3
+ metadata.gz: d9edf6b451d6dd432680716812884d42b96cb2bc
4
+ data.tar.gz: ad2a991a3c52a084ca35d064748dcf221833d5a0
5
5
  SHA512:
6
- metadata.gz: 1fcc02a2825ce7515ada10d5fbdcab305d05288a8a08e63632f4316a9bebb41495bd11e9762c7762199ab68d40ca4e4e674ed9e7f81c9f9448da748c03f8316b
7
- data.tar.gz: ac92cac11525affb6fd81a07611582f79f025702f52ce223a1c98c8b9c124f0c2c20fdc0419e96561012ef77fe9d0823fa4a576f5946d33b0d594a4e905eb981
6
+ metadata.gz: 2f441b31252807ee4812f623336ab197bd735505773933b85ae72d4db6b8fc88300b5106c6d41459c0d29d7d8a3dbf12ef0a535eb713bdf6a8f10a719cfba5c1
7
+ data.tar.gz: 267dfb58de727b25674da456dddea387d3ec76e56edb9247f19ec915720c0655600b12af68f5b945a8ef673c6bcb324f61a7b81a4f98fe3d022a4896279cf71e
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  vendor/bundle
19
+ .ruby-version
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 1.9.3
3
+ - 2.0.0
4
+ - 2.1.*
5
+ - 2.2.*
6
+ gemfile:
7
+ - Gemfile
8
+ - Gemfile.fluentd.lt.0.12
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # 0.2.0
2
+
3
+ Changes:
4
+
5
+ * Refactoring
6
+
7
+ Fixes:
8
+
9
+ * Fix so that `time_locale` option works for time field in mail body
10
+
11
+ Enhancements:
12
+
13
+ * Add `localtime` option
14
+
1
15
  # 0.1.2
2
16
 
3
17
  Enhancement:
data/Gemfile CHANGED
@@ -1,7 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in fluent-plugin-mail.gemspec
4
3
  gemspec
5
-
6
-
7
-
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'fluentd', '~> 0.10.43'
4
+ gemspec
data/README.md CHANGED
@@ -211,6 +211,29 @@ log server("/etc/td-agent/td-agent.conf")
211
211
 
212
212
  See [CHANGELOG.md](CHANGELOG.md) for more details.
213
213
 
214
+ ## Development
215
+
216
+ Run mail server using [mailcatcher](http://mailcatcher.me/) gem as:
217
+
218
+ ```
219
+ $ gem install mailcatcher
220
+ $ mailcactcher
221
+ ```
222
+
223
+ It starts STMP server on localhost:1025, and has Web UI running on localhost:1080.
224
+
225
+ Run Fluentd as:
226
+
227
+ ```
228
+ $ bundle exec fluentd -c example.conf
229
+ ```
230
+
231
+ Put a message to the Fluentd as:
232
+
233
+ ```
234
+ $ echo '{"message":"This is a test"}' | bundle exec fluent-cat mail.test
235
+ ```
236
+
214
237
  ## Copyright
215
238
 
216
239
  * Copyright
data/example.conf ADDED
@@ -0,0 +1,20 @@
1
+ <source>
2
+ type forward
3
+ </source>
4
+
5
+ <match mail.test>
6
+ type mail
7
+ log_level debug
8
+ host localhost
9
+ port 1025
10
+ from foo@example.com
11
+ to bar@example.com
12
+ bcc baz@example.com
13
+ subject this is a test
14
+ message Hello from out_mail\n[%s] %s
15
+ message_out_keys time,message
16
+ time_key time
17
+ time_locale Asia/Taipei
18
+ # localtime false
19
+ time_format %Y-%m-%d %H:%M:%S %z
20
+ </match>
@@ -12,9 +12,10 @@ Gem::Specification.new do |gem|
12
12
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
13
13
  gem.name = "fluent-plugin-mail"
14
14
  gem.require_paths = ["lib"]
15
- gem.version = '0.1.2'
15
+ gem.version = '0.2.0'
16
16
 
17
17
  gem.add_runtime_dependency "fluentd"
18
18
  gem.add_runtime_dependency "string-scrub" if RUBY_VERSION.to_f < 2.1
19
19
  gem.add_development_dependency "rake"
20
+ gem.add_development_dependency "test-unit"
20
21
  end
@@ -8,26 +8,27 @@ class Fluent::MailOutput < Fluent::Output
8
8
  define_method("log") { $log }
9
9
  end
10
10
 
11
- config_param :out_keys, :string, :default => ""
12
- config_param :message, :string, :default => nil
13
- config_param :message_out_keys, :string, :default => ""
14
- config_param :time_key, :string, :default => nil
15
- config_param :time_format, :string, :default => nil
16
- config_param :tag_key, :string, :default => 'tag'
17
- config_param :host, :string
18
- config_param :port, :integer, :default => 25
19
- config_param :domain, :string, :default => 'localdomain'
20
- config_param :user, :string, :default => nil
21
- config_param :password, :string, :default => nil
22
- config_param :from, :string, :default => 'localhost@localdomain'
23
- config_param :to, :string, :default => ''
24
- config_param :cc, :string, :default => ''
25
- config_param :bcc, :string, :default => ''
26
- config_param :subject, :string, :default => 'Fluent::MailOutput plugin'
27
- config_param :subject_out_keys, :string, :default => ""
28
- config_param :enable_starttls_auto, :bool, :default => false
29
- config_param :enable_tls, :bool, :default => false
30
- config_param :time_locale, :default => nil
11
+ config_param :out_keys, :string, :default => ""
12
+ config_param :message, :string, :default => nil
13
+ config_param :message_out_keys, :string, :default => ""
14
+ config_param :time_key, :string, :default => nil
15
+ config_param :tag_key, :string, :default => 'tag'
16
+ config_param :host, :string
17
+ config_param :port, :integer, :default => 25
18
+ config_param :domain, :string, :default => 'localdomain'
19
+ config_param :user, :string, :default => nil
20
+ config_param :password, :string, :default => nil
21
+ config_param :from, :string, :default => 'localhost@localdomain'
22
+ config_param :to, :string, :default => ''
23
+ config_param :cc, :string, :default => ''
24
+ config_param :bcc, :string, :default => ''
25
+ config_param :subject, :string, :default => 'Fluent::MailOutput plugin'
26
+ config_param :subject_out_keys, :string, :default => ""
27
+ config_param :enable_starttls_auto, :bool, :default => false
28
+ config_param :enable_tls, :bool, :default => false
29
+ config_param :time_format, :string, :default => "%F %T %z"
30
+ config_param :localtime, :bool, :default => true
31
+ config_param :time_locale, :default => nil
31
32
 
32
33
  def initialize
33
34
  super
@@ -47,10 +48,16 @@ class Fluent::MailOutput < Fluent::Output
47
48
  raise Fluent::ConfigError, "Either 'message' or 'out_keys' must be specifed."
48
49
  end
49
50
 
50
- begin
51
- @message % (['1'] * @message_out_keys.length) if @message
52
- rescue ArgumentError
53
- raise Fluent::ConfigError, "string specifier '%s' of message and message_out_keys specification mismatch"
51
+ if @message
52
+ begin
53
+ @message % (['1'] * @message_out_keys.length)
54
+ rescue ArgumentError
55
+ raise Fluent::ConfigError, "string specifier '%s' of message and message_out_keys specification mismatch"
56
+ end
57
+ @create_message_proc = Proc.new {|tag, time, record| create_formatted_message(tag, time, record) }
58
+ else
59
+ # The default uses the old `key=value` format for old version compatibility
60
+ @create_message_proc = Proc.new {|tag, time, record| create_key_value_message(tag, time, record) }
54
61
  end
55
62
 
56
63
  begin
@@ -58,22 +65,9 @@ class Fluent::MailOutput < Fluent::Output
58
65
  rescue ArgumentError
59
66
  raise Fluent::ConfigError, "string specifier '%s' of subject and subject_out_keys specification mismatch"
60
67
  end
61
-
62
- if @time_key
63
- if @time_format
64
- f = @time_format
65
- tf = Fluent::TimeFormatter.new(f, @localtime)
66
- @time_format_proc = tf.method(:format)
67
- @time_parse_proc = Proc.new {|str| Time.strptime(str, f).to_i }
68
- else
69
- @time_format_proc = Proc.new {|time| time.to_s }
70
- @time_parse_proc = Proc.new {|str| str.to_i }
71
- end
72
- end
73
68
  end
74
69
 
75
70
  def start
76
-
77
71
  end
78
72
 
79
73
  def shutdown
@@ -84,41 +78,36 @@ class Fluent::MailOutput < Fluent::Output
84
78
  subjects = []
85
79
 
86
80
  es.each {|time,record|
87
- if @message
88
- messages << create_formatted_message(tag, time, record)
89
- else
90
- messages << create_key_value_message(tag, time, record)
91
- end
81
+ messages << @create_message_proc.call(tag, time, record)
92
82
  subjects << create_formatted_subject(tag, time, record)
93
83
  }
94
84
 
95
- messages.each_with_index do |msg, i|
85
+ (0...messages.size).each do |i|
86
+ message = messages[i]
96
87
  subject = subjects[i]
97
88
  begin
98
- res = sendmail(subject, msg)
89
+ sendmail(subject, message)
99
90
  rescue => e
100
- log.warn "out_mail: failed to send notice to #{@host}:#{@port}, subject: #{subject}, message: #{msg}, error_class: #{e.class}, error_message: #{e.message}, error_backtrace: #{e.backtrace.first}"
91
+ log.warn "out_mail: failed to send notice to #{@host}:#{@port}, subject: #{subject}, message: #{message}, " <<
92
+ "error_class: #{e.class}, error_message: #{e.message}, error_backtrace: #{e.backtrace.first}"
101
93
  end
102
94
  end
103
95
 
104
96
  chain.next
105
97
  end
106
98
 
107
- def format(tag, time, record)
108
- "#{Time.at(time).strftime('%Y/%m/%d %H:%M:%S')}\t#{tag}\t#{record.to_json}\n"
109
- end
110
-
99
+ # The old `key=value` format for old version compatibility
111
100
  def create_key_value_message(tag, time, record)
112
101
  values = []
113
102
 
114
- @out_keys.each do |key|
103
+ values << @out_keys.each do |key|
115
104
  case key
116
105
  when @time_key
117
- values << @time_format_proc.call(time)
106
+ format_time(time, @time_format)
118
107
  when @tag_key
119
- values << tag
108
+ tag
120
109
  else
121
- values << "#{key}: #{record[key].to_s}"
110
+ "#{key}: #{record[key].to_s}"
122
111
  end
123
112
  end
124
113
 
@@ -131,7 +120,7 @@ class Fluent::MailOutput < Fluent::Output
131
120
  values = @message_out_keys.map do |key|
132
121
  case key
133
122
  when @time_key
134
- @time_format_proc.call(time)
123
+ format_time(time, @time_format)
135
124
  when @tag_key
136
125
  tag
137
126
  else
@@ -143,24 +132,13 @@ class Fluent::MailOutput < Fluent::Output
143
132
  with_scrub(message) {|str| str.gsub(/\\n/, "\n") }
144
133
  end
145
134
 
146
- def with_scrub(string)
147
- begin
148
- return yield(string)
149
- rescue ArgumentError => e
150
- raise e unless e.message.index("invalid byte sequence in") == 0
151
- log.info "out_mail: invalid byte sequence is replaced in #{string}"
152
- string.scrub!('?')
153
- retry
154
- end
155
- end
156
-
157
135
  def create_formatted_subject(tag, time, record)
158
136
  values = []
159
137
 
160
138
  values = @subject_out_keys.map do |key|
161
139
  case key
162
140
  when @time_key
163
- @time_format_proc.call(time)
141
+ format_time(time, @time_format)
164
142
  when @tag_key
165
143
  tag
166
144
  else
@@ -186,16 +164,14 @@ class Fluent::MailOutput < Fluent::Output
186
164
  subject = subject.force_encoding('binary')
187
165
  body = msg.force_encoding('binary')
188
166
 
189
- if time_locale
190
- date = Time::now.timezone(time_locale)
191
- else
192
- date = Time::now
193
- end
167
+ # Date: header has timezone, so usually it is not necessary to set locale explicitly
168
+ # But, for people who would see mail header text directly, the locale information may help something
169
+ # (for example, they can tell the sender should live in Tokyo if +0900)
170
+ date = format_time(Time.now, "%a, %d %b %Y %X %z")
194
171
 
195
172
  mid = sprintf("<%s@%s>", SecureRandom.uuid, SecureRandom.uuid)
196
-
197
- debug_msg = smtp.send_mail(<<EOS, @from, @to.split(/,/), @cc.split(/,/), @bcc.split(/,/))
198
- Date: #{date.strftime("%a, %d %b %Y %X %z")}
173
+ content = <<EOF
174
+ Date: #{date}
199
175
  From: #{@from}
200
176
  To: #{@to}
201
177
  Cc: #{@cc}
@@ -206,20 +182,37 @@ Mime-Version: 1.0
206
182
  Content-Type: text/plain; charset=utf-8
207
183
 
208
184
  #{body}
209
- EOS
210
- log.debug "out_mail: email send response: #{debug_msg}"
185
+ EOF
186
+ response = smtp.send_mail(content, @from, @to.split(/,/), @cc.split(/,/), @bcc.split(/,/))
187
+ log.debug "out_mail: content: #{content.gsub("\n", "\\n")}"
188
+ log.debug "out_mail: email send response: #{response.string.chomp}"
211
189
  smtp.finish
212
190
  end
213
191
 
214
- end
192
+ def format_time(time, time_format)
193
+ # Fluentd >= v0.12's TimeFormatter supports timezone, but v0.10 does not
194
+ if @time_locale
195
+ with_timezone(@time_locale) { Fluent::TimeFormatter.new(time_format, @localtime).format(time) }
196
+ else
197
+ Fluent::TimeFormatter.new(time_format, @localtime).format(time)
198
+ end
199
+ end
215
200
 
216
- class Time
217
- def timezone(timezone = 'UTC')
218
- old = ENV['TZ']
219
- utc = self.dup.utc
220
- ENV['TZ'] = timezone
221
- output = utc.localtime
222
- ENV['TZ'] = old
223
- output
201
+ def with_timezone(tz)
202
+ oldtz, ENV['TZ'] = ENV['TZ'], tz
203
+ yield
204
+ ensure
205
+ ENV['TZ'] = oldtz
206
+ end
207
+
208
+ def with_scrub(string)
209
+ begin
210
+ return yield(string)
211
+ rescue ArgumentError => e
212
+ raise e unless e.message.index("invalid byte sequence in") == 0
213
+ log.info "out_mail: invalid byte sequence is replaced in #{string}"
214
+ string.scrub!('?')
215
+ retry
216
+ end
224
217
  end
225
218
  end
data/test/helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rubygems'
2
2
  require 'bundler'
3
3
  begin
4
- Bundler.setup(:default, :development)
4
+ Bundler.setup(:default, :test)
5
5
  rescue Bundler::BundlerError => e
6
6
  $stderr.puts e.message
7
7
  $stderr.puts "Run `bundle install` to install missing gems"
@@ -1,4 +1,4 @@
1
- require 'helper'
1
+ require_relative '../helper'
2
2
 
3
3
  class MailOutputTest < Test::Unit::TestCase
4
4
  def setup
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-mail
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yuichi UEMURA
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-04-08 00:00:00.000000000 Z
12
+ date: 2015-06-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fluentd
@@ -39,6 +39,20 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: test-unit
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
42
56
  description: output plugin for Mail
43
57
  email:
44
58
  - yuichi.u@gmail.com
@@ -48,11 +62,14 @@ extensions: []
48
62
  extra_rdoc_files: []
49
63
  files:
50
64
  - ".gitignore"
65
+ - ".travis.yml"
51
66
  - CHANGELOG.md
52
67
  - Gemfile
68
+ - Gemfile.fluentd.lt.0.12
53
69
  - LICENSE
54
70
  - README.md
55
71
  - Rakefile
72
+ - example.conf
56
73
  - fluent-plugin-mail.gemspec
57
74
  - lib/fluent/plugin/out_mail.rb
58
75
  - test/helper.rb