lib/fluent/plugin/out_mail.rb in fluent-plugin-mail-0.2.3 vs lib/fluent/plugin/out_mail.rb in fluent-plugin-mail-0.2.4
- old
+ new
@@ -40,12 +40,18 @@
config_param :from, :string, :default => 'localhost@localdomain'
desc "Mail destination (To)"
config_param :to, :string, :default => ''
desc "Mail destination (Cc)"
config_param :cc, :string, :default => ''
- desc "Mail destination (BCc)"
+ desc "Mail destination (Bcc)"
config_param :bcc, :string, :default => ''
+ desc "Dyanmically identify mail destination (To) from records"
+ config_param :to_key, :string, :default => nil
+ desc "Dynamically identify mail destination (Cc) from records"
+ config_param :cc_key, :string, :default => nil
+ desc "Dynamically identify mail destination (Bcc) from records"
+ config_param :bcc_key, :string, :default => nil
desc "Format string to construct mail subject"
config_param :subject, :string, :default => 'Fluent::MailOutput plugin'
desc "Specify comma delimited keys output to `subject`"
config_param :subject_out_keys, :string, :default => ""
desc "If set to true, enable STARTTLS"
@@ -88,10 +94,39 @@
else
# The default uses the old `key=value` format for old version compatibility
@create_message_proc = Proc.new {|tag, time, record| create_key_value_message(tag, time, record) }
end
+ if @to_key or @cc_key or @bcc_key
+ @process_event_stream_proc = Proc.new {|tag, es|
+ messages = []
+ subjects = []
+ dests = []
+
+ es.each do |time, record|
+ messages << @create_message_proc.call(tag, time, record)
+ subjects << create_formatted_subject(tag, time, record)
+ dests << %w(to cc bcc).each_with_object({}){|t, dest| dest[t] = create_dest_addr(t, record) }
+ end
+
+ [messages, subjects, dests]
+ }
+ else
+ @process_event_stream_proc = Proc.new {|tag, es|
+ messages = []
+ subjects = []
+ dests = []
+
+ es.each do |time, record|
+ messages << @create_message_proc.call(tag, time, record)
+ subjects << create_formatted_subject(tag, time, record)
+ end
+
+ [messages, subjects, dests]
+ }
+ end
+
begin
@subject % (['1'] * @subject_out_keys.length)
rescue ArgumentError
raise Fluent::ConfigError, "string specifier '%s' of subject and subject_out_keys specification mismatch"
end
@@ -102,23 +137,17 @@
def shutdown
end
def emit(tag, es, chain)
- messages = []
- subjects = []
+ messages, subjects, dests = @process_event_stream_proc.call(tag, es)
- es.each {|time,record|
- messages << @create_message_proc.call(tag, time, record)
- subjects << create_formatted_subject(tag, time, record)
- }
-
- (0...messages.size).each do |i|
- message = messages[i]
+ messages.each_with_index do |message, i|
subject = subjects[i]
+ dest = dests[i]
begin
- sendmail(subject, message)
+ sendmail(subject, message, dest)
rescue => e
log.warn "out_mail: failed to send notice to #{@host}:#{@port}, subject: #{subject}, message: #{message}, " <<
"error_class: #{e.class}, error_message: #{e.message}, error_backtrace: #{e.backtrace.first}"
end
end
@@ -177,11 +206,11 @@
end
@subject % values
end
- def sendmail(subject, msg)
+ def sendmail(subject, msg, dest = nil)
smtp = Net::SMTP.new(@host, @port)
if @user and @password
smtp_auth_option = [@domain, @user, @password, :plain]
smtp.enable_starttls if @enable_starttls_auto
@@ -191,31 +220,34 @@
smtp.start
end
subject = subject.force_encoding('binary')
body = msg.force_encoding('binary')
+ to = (dest && dest['to']) ? dest['to'] : @to
+ cc = (dest && dest['cc']) ? dest['cc'] : @cc
+ bcc = (dest && dest['bcc']) ? dest['bcc'] : @bcc
# Date: header has timezone, so usually it is not necessary to set locale explicitly
# But, for people who would see mail header text directly, the locale information may help something
# (for example, they can tell the sender should live in Tokyo if +0900)
date = format_time(Time.now, "%a, %d %b %Y %X %z")
mid = sprintf("<%s@%s>", SecureRandom.uuid, SecureRandom.uuid)
content = <<EOF
Date: #{date}
From: #{@from}
-To: #{@to}
-Cc: #{@cc}
-Bcc: #{@bcc}
+To: #{to}
+Cc: #{cc}
+Bcc: #{bcc}
Subject: #{subject}
Message-Id: #{mid}
Mime-Version: 1.0
Content-Type: #{@content_type}
#{body}
EOF
- response = smtp.send_mail(content, @from, @to.split(/,/), @cc.split(/,/), @bcc.split(/,/))
+ response = smtp.send_mail(content, @from, to.split(/,/), cc.split(/,/), bcc.split(/,/))
log.debug "out_mail: content: #{content.gsub("\n", "\\n")}"
log.debug "out_mail: email send response: #{response.string.chomp}"
smtp.finish
end
@@ -241,8 +273,18 @@
rescue ArgumentError => e
raise e unless e.message.index("invalid byte sequence in") == 0
log.info "out_mail: invalid byte sequence is replaced in #{string}"
string.scrub!('?')
retry
+ end
+ end
+
+ def create_dest_addr(dest_type, record)
+ addr = instance_variable_get(:"@#{dest_type}")
+ dest_key = instance_variable_get(:"@#{dest_type}_key")
+ if dest_key
+ return record[dest_key] || addr
+ else
+ return addr
end
end
end