class Fluent::MailOutput
Public Class Methods
desc(description)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 14 def desc(description) end
new()
click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_mail.rb, line 72 def initialize super require 'net/smtp' require 'string/scrub' if RUBY_VERSION.to_f < 2.1 end
Public Instance Methods
configure(conf)
click to toggle source
Calls superclass method
# File lib/fluent/plugin/out_mail.rb, line 78 def configure(conf) super if @out_keys.empty? and @message.nil? raise Fluent::ConfigError, "Either 'message' or 'out_keys' must be specifed." end if @message begin @message % (['1'] * @message_out_keys.length) rescue ArgumentError raise Fluent::ConfigError, "string specifier '%s' of message and message_out_keys specification mismatch" end @create_message_proc = Proc.new {|tag, time, record| create_formatted_message(tag, time, record) } 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 end
create_dest_addr(dest_type, record)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 279 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
create_formatted_message(tag, time, record)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 174 def create_formatted_message(tag, time, record) values = [] values = @message_out_keys.map do |key| case key when @time_key format_time(time, @time_format) when @tag_key tag else record[key].to_s end end message = (@message % values) with_scrub(message) {|str| str.gsub(/\\n/, "\n") } end
create_formatted_subject(tag, time, record)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 192 def create_formatted_subject(tag, time, record) values = [] values = @subject_out_keys.map do |key| case key when @time_key format_time(time, @time_format) when @tag_key tag else record[key].to_s end end @subject % values end
create_key_value_message(tag, time, record)
click to toggle source
The old `key=value` format for old version compatibility
# File lib/fluent/plugin/out_mail.rb, line 157 def create_key_value_message(tag, time, record) values = [] values = @out_keys.map do |key| case key when @time_key format_time(time, @time_format) when @tag_key tag else "#{key}: #{record[key].to_s}" end end values.join("\n") end
emit(tag, es, chain)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 139 def emit(tag, es, chain) messages, subjects, dests = @process_event_stream_proc.call(tag, es) messages.each_with_index do |message, i| subject = subjects[i] dest = dests[i] begin 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 chain.next end
format_time(time, time_format)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 252 def format_time(time, time_format) # Fluentd >= v0.12's TimeFormatter supports timezone, but v0.10 does not if @time_locale with_timezone(@time_locale) { Fluent::TimeFormatter.new(time_format, @localtime).format(time) } else Fluent::TimeFormatter.new(time_format, @localtime).format(time) end end
sendmail(subject, msg, dest = nil)
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 209 def sendmail(subject, msg, dest = nil) smtp = Net::SMTP.new(@host, @port) if @user and @password smtp_auth_option = [@domain, @user, @password, @authtype.to_sym] smtp.enable_starttls if @enable_starttls_auto smtp.enable_tls if @enable_tls smtp.start(@domain, @user, @password, @authtype.to_sym) else 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} 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(/,/)) log.debug "out_mail: content: #{content.gsub("\n", "\\n")}" log.debug "out_mail: email send response: #{response.string.chomp}" smtp.finish end
shutdown()
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 136 def shutdown end
start()
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 133 def start end
with_scrub(string) { |string| ... }
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 268 def with_scrub(string) begin return yield(string) 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
with_timezone(tz) { || ... }
click to toggle source
# File lib/fluent/plugin/out_mail.rb, line 261 def with_timezone(tz) oldtz, ENV['TZ'] = ENV['TZ'], tz yield ensure ENV['TZ'] = oldtz end