fluent-plugin-mail 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +8 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +0 -4
- data/Gemfile.fluentd.lt.0.12 +4 -0
- data/README.md +23 -0
- data/example.conf +20 -0
- data/fluent-plugin-mail.gemspec +2 -1
- data/lib/fluent/plugin/out_mail.rb +78 -85
- data/test/helper.rb +1 -1
- data/test/plugin/test_out_mail.rb +1 -1
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d9edf6b451d6dd432680716812884d42b96cb2bc
|
4
|
+
data.tar.gz: ad2a991a3c52a084ca35d064748dcf221833d5a0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f441b31252807ee4812f623336ab197bd735505773933b85ae72d4db6b8fc88300b5106c6d41459c0d29d7d8a3dbf12ef0a535eb713bdf6a8f10a719cfba5c1
|
7
|
+
data.tar.gz: 267dfb58de727b25674da456dddea387d3ec76e56edb9247f19ec915720c0655600b12af68f5b945a8ef673c6bcb324f61a7b81a4f98fe3d022a4896279cf71e
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
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>
|
data/fluent-plugin-mail.gemspec
CHANGED
@@ -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.
|
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,
|
12
|
-
config_param :message,
|
13
|
-
config_param :message_out_keys,
|
14
|
-
config_param :time_key,
|
15
|
-
config_param :
|
16
|
-
config_param :
|
17
|
-
config_param :
|
18
|
-
config_param :
|
19
|
-
config_param :
|
20
|
-
config_param :
|
21
|
-
config_param :
|
22
|
-
config_param :
|
23
|
-
config_param :
|
24
|
-
config_param :
|
25
|
-
config_param :
|
26
|
-
config_param :
|
27
|
-
config_param :
|
28
|
-
config_param :
|
29
|
-
config_param :
|
30
|
-
config_param :
|
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
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
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.
|
85
|
+
(0...messages.size).each do |i|
|
86
|
+
message = messages[i]
|
96
87
|
subject = subjects[i]
|
97
88
|
begin
|
98
|
-
|
89
|
+
sendmail(subject, message)
|
99
90
|
rescue => e
|
100
|
-
log.warn "out_mail: failed to send notice to #{@host}:#{@port}, subject: #{subject}, message: #{
|
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
|
-
|
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
|
-
|
106
|
+
format_time(time, @time_format)
|
118
107
|
when @tag_key
|
119
|
-
|
108
|
+
tag
|
120
109
|
else
|
121
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
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
|
-
|
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
|
-
|
210
|
-
|
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
|
-
|
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
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
ENV['TZ'] =
|
221
|
-
|
222
|
-
|
223
|
-
|
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
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.
|
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-
|
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
|