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 +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
|