Aug/090
Are My Emails Getting Through? The Need to Monitor Email Deliverability Part II
TechOps Guy: Dave
I wanted to follow up on Jason’s post about determining if your e-mails are getting through with what we actually implemented. In order to find out whether the big guys (hotmail,gmail,AOL or earthilink) have accepted our (opt-in) e-mail message I created the following Nagios check script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | #!/usr/bin/ruby require '/usr/local/nagios/libexec/pop_ssl' require 'net/imap' require 'date' require 'date/format' # require 'imap' require '/usr/lib64/ruby/gems/1.8/gems/hotmailer-1.0.1/lib/hotmailer.rb' require 'rubygems' # require 'hotmailer' require 'getoptlong' # require 'rdoc/usage' class PlainAuthenticator def process(data) return "/0#{@user}/0#{@password}" end private def initialize(user, password) @user = user @password = password end end Net::IMAP.add_authenticator('PLAIN', PlainAuthenticator) opts = GetoptLong.new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ], [ '--mailhost', '-m', GetoptLong::REQUIRED_ARGUMENT ], [ '--username', '-u', GetoptLong::REQUIRED_ARGUMENT ], [ '--password', '-p', GetoptLong::REQUIRED_ARGUMENT ], [ '--port', '-o', GetoptLong::REQUIRED_ARGUMENT ], [ '--search', '-s', GetoptLong::REQUIRED_ARGUMENT ], [ '--age', '-a', GetoptLong::REQUIRED_ARGUMENT ], [ '--transport', '-t', GetoptLong::REQUIRED_ARGUMENT ] ) mailhost = nil username = nil password = nil searchString = nil transport="POP3" port = nil age = 1 opts.each do |opt, arg| case opt when '--help' # RDoc::usage when '--mailhost' mailhost = arg when '--username' username = arg when '--password' password = arg when '--search' searchString = arg when '--port' port = arg when '--transport' transport = arg end end i = 0 #Figure the out how far back we will search in a mailbox day = Date.today-age imapFormatedDate = day.strftime(fmt="%d-%b-%Y") if transport == "securePOP3" Net::POP3.enable_ssl(OpenSSL::SSL::VERIFY_NONE) end if ((transport == "POP3") or (transport == "securePOP3")) pop = Net::POP3.new(mailhost, port) pop.start( username,password) if pop.mails.empty? else pop.each_mail do |m| date = nil m.header.each do |h| if h =~ /Date/ date = Date.parse(h) end end if date >= day m.pop.each do |f| # puts "#{f}" if f =~ /#{searchString}/ i += 1 end end end end end pop.finish end if transport == "IMAP" imap = Net::IMAP.new(mailhost) imap.login(username, password) messages = imap.status("inbox", ["MESSAGES"]) if messages["MESSAGES"] >= 1 imap.select('INBOX') imap.search(["SINCE", imapFormatedDate]).each do |message_id| msg = imap.fetch(message_id, "(UID RFC822.SIZE ENVELOPE BODY[TEXT])")[0] body = msg.attr["BODY[TEXT]"] # puts "#{body}" envelope = imap.fetch(message_id, "ENVELOPE")[0].attr["ENVELOPE"] if (envelope.subject =~ /#{searchString}/) or (body =~ /#{searchString}/) # puts "#{envelope.from[0].name}: \t#{envelope.subject}" i += 1 end imap.store(message_id, "+FLAGS", [:Deleted]) end imap.logout end end if transport == "hotmail" hotty = Hotmailer.new(username, password) hotty.login messages = hotty.messages messages.each do |f| tempdate = f.date+" 2007" tempdate.gsub!(/(.*)( )(.*)/,'\1 \3') date = Date.parse(tempdate) if date >= day if (f.subject =~ /#{searchString}/) or (f.body =~ /#{searchString}/) i += 1 end end end end if i >= 1 puts "Found #{i} Messages matching \"#{searchString}\"" exit(anInteger=0) else puts "No Messages matching \"#{searchString}\"" exit(anInteger=2) end |
The script should be fairly useful even today with exception of checking hotmail, since I originally wrote this hotmail has redesigned their interface break the hotmailer module I found which screen scraped the site.
So good luck and I hope your properly opted in mail is getting through.
Aug/090
Making RRD output readable
TechOps Guy: Dave
I have been doing a lot of work lately with creating new data points to monitor with cacti and when trouble shooting why a new data point is not working I have been running into a bit of an issue. I can see what my script is handing to the cacti poller, I can see what cacti is putting in the RRD file (with increased logging), but I can’t easily see what RRD has done with that data before handing off to cacti. By default RRD store’s the time stamps in Epoch Time (seconds since midnight on Jan 1st, 1970) and data in scientific notation. Now, I don’t know about you, but I can’t read either of those without some help so here is my little Ruby script helper
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/usr/bin/env ruby # Author: W. David Nash III # Version 0.1 # August 3, 2009 count = 0 STDIN.each do|l| count += 1 printf("%-3i | ",count) if !l.match(/^\d+/) header = l.to_s.split else (td, data) = l.split(/:/).map time = Time.at(td.to_i) printf("%s:", time.strftime("%Y-%m-%d %H:%M:%S")) data.to_s.split.map do |d| if (d.eql? "nan") then d = "0.00" end printf(" | %20.2f", d.chomp) end end if(count == 1) printf("%20s", "Time") header.each do |h| printf(" | %20s",h) end end puts "\n" end |
and you use it like so
rrdtool fetch rra/<RRD FILE NAME>.rrd AVERAGE -s -1h -r 60 | ./readRRD.rb |
and here is some sample output
1 | Time | Heap_Mem_Committed | Heap_Mem_Max | Heap_Mem_Used | Non_Heap_Mem_Commit | Non_Heap_Mem_Init | Non_Heap_Mem_Max | Non_Heap_Mem_Used | CPU_TIME | User_Time | Thread_Count | Peak_Thread_Count | Heap_Mem_Init 2 | 3 | 2009-08-03 13:18:00: | 213295104.00 | 532742144.00 | 130720632.67 | 36405248.00 | 12746752.00 | 100663296.00 | 36383328.00 | 623333333.33 | 531666666.67 | 111.33 | 184.00 | 0.00 4 | 2009-08-03 13:19:00: | 213295104.00 | 532742144.00 | 132090801.60 | 36405248.00 | 12746752.00 | 100663296.00 | 36383328.00 | 1818000000.00 | 1704000000.00 | 111.80 | 184.00 | 0.00 5 | 2009-08-03 13:20:00: | 213295104.00 | 532742144.00 | 122721880.67 | 36405248.00 | 12746752.00 | 100663296.00 | 36383328.00 | 2186666666.70 | 2057500000.00 | 112.92 | 184.00 | 0.00 |