Created
June 2, 2012 05:56
-
-
Save minimum2scp/2856853 to your computer and use it in GitHub Desktop.
postfixのactiveとかincomingとかをinotifyでイベント監視
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env ruby1.9.1 | |
# coding: utf-8 | |
require 'find' | |
require 'rb-inotify' | |
QUEUE_DIR = '/var/spool/postfix' | |
PID_FILE = "/tmp/#{File.basename(__FILE__)}.pid" | |
OUT_FILE = "/tmp/#{File.basename(__FILE__)}.out" | |
logger = ->(msg,*args){ | |
if $DEBUG | |
t = Time.now | |
if args.empty? | |
puts "#{t.strftime('%Y-%m-%d %H:%M:%S.%3N')} : #{msg}" | |
else | |
puts "#{t.strftime('%Y-%m-%d %H:%M:%S.%3N')} : #{msg}" % args | |
end | |
end | |
} | |
notifier = INotify::Notifier.new | |
# 監視対象イベント | |
events = [:create, :delete, :moved_from, :moved_to] | |
# カウンタ(キー:イベント, 値:回数) | |
counter = Hash.new(0) | |
# ファイルへのイベント発生時のコールバック | |
countup = ->(ev){ | |
logger.call [ev.flags, ev.name, ev.absolute_name].inspect | |
events.each do |e| | |
counter[e]+=1 if ev.flags.include? e | |
end | |
} | |
# ディレクトリで発生するイベントを再帰的に監視 | |
watch = ->(fpath){ | |
case fpath2 = fpath.sub(QUEUE_DIR, '').sub(/^$/,'/') | |
## postfix の active, incoming ,... を監視する | |
when '/', %r<^/(active|incoming|defer|deferred|corrupt|hold)/?> | |
logger.call "watch: add %s", fpath2 | |
notifier.watch(fpath, *events) do |ev| | |
case | |
when ev.flags.include?(:isdir) && ev.flags.include?(:create) | |
watch[ev.absolute_name] | |
when !ev.flags.include?(:isdir) && ev.name =~ /\A[0-9a-fA-F]+\Z/ | |
countup[ev] | |
end | |
end | |
else | |
logger.call "watch: ignore %s", fpath | |
end | |
} | |
# /var/spool/postfix 以下のディレクトリを探して watch | |
Find.find QUEUE_DIR do |fpath| | |
watch[fpath] if File.directory? fpath | |
end | |
# PIDファイル(簡単にSIGUSR1を送れるように) | |
File.open(PID_FILE, 'w'){ |fh| fh << $$ } | |
# メインループ | |
begin | |
Signal.trap :USR1, 'DEFAULT' | |
notifier.run | |
rescue SignalException => e | |
if e.message == 'SIGUSR1' | |
Signal.trap :USR1, 'IGNORE' | |
logger.call "SIGUSR1 received, writing %s...", OUT_FILE | |
open(OUT_FILE, 'w') do |fh| | |
events.each do |ev| fh << "%s = %d\n" % [ ev, counter[ev] ] end | |
end | |
#sleep 1 | |
logger.call "resume inotify event loop" | |
retry | |
else | |
raise e | |
end | |
ensure | |
File.unlink PID_FILE | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment