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