月曜日, 9月 06, 2010

Rubyでログファイルを定期的に監視

2008/04/03perlfreak.vox.comより転載)

RubyGemsでtmailをインストールしてある前提。
ログファイルには指定するキーワードの他にサイトIDが出力されている前提。
これを5分おきに実行。

=== ( log_check.rb ここから) ===
#!/usr/bin/env ruby

require 'rubygems'
require 'tmail'
require 'iconv'
require 'net/smtp'

# ホスト名
host = `/bin/hostname`.chomp

# ログファイル
log_file = '/var/log/hoge.log'

# フラグ用ディレクトリ
flag_dir = '/var/run/log_check/'

# キーワード
log_keyword = '混雑'

# チェック間隔(秒)
interval = 300

# アラートまでのチェック回数
alert_check_count = 3

# 送信先
mailto = [
'foo@bar.com'
]

## prefix作成メソッド
def make_prefix( num )
return "_" + num.to_s + "_"
end

## ディレクトリ下ファイル名からのサイトID取得メソッド
def get_flag_site_list( dir_path, prefix_num )
prefix = make_prefix( prefix_num )
site_id_ary = Array.new
file_path_ary = Dir.glob( dir_path + "#{prefix}*" )
file_path_ary.each do |file_path|
/^#{prefix}(.+)$/ =~ File.split( file_path )[1]
site_id_ary.push( $1 )
end

return site_id_ary
end

## ログファイルからキーワードを含む行のサイトID取得メソッド
def get_log_site_list( sec, keyword )
site_id_ary = Array.new
boundary_time = (Time.now - sec).strftime( "[%Y/%m/%d %H:%M:%S]" )
tail_lines = sec * 50
grep_result = `/usr/bin/tail -#{tail_lines} #{log_file} | /bin/grep "#{keyword}"`
grep_result.split( /\n/ ).each do |line|
line_ary = line.split( /\s+/ )
site_id = line_ary[3]
time_stamp = line_ary[0] + ' ' + line_ary[1]
if time_stamp >= boundary_time
if !site_id_ary.include?( site_id )
site_id_ary.push( site_id )
end
end
end

return site_id_ary
end

## メール送信メソッド
def send_mail( mailto, host, site_id, alt )
subject = "混雑リカバリ (" + site_id + ")"
if alt == "alert"
subject = "混雑アラート (" + site_id + ")"
end

from = 'system@bar.com'
mesg = host + "\n\n" + site_id

mail = TMail::Mail.new
mail.to = mailto
mail.cc = ['']
mail.bcc = ['']
mail.from = from
mail.subject = Iconv.conv( 'ISO-2022-JP', 'EUC-JP', subject )
mail.date = Time.now
mail.mime_version = '1.0'
mail.set_content_type( 'text', 'plain', {'charset' => 'iso-2022-jp'} )
mail.encoding = '7bit'
mail.body = Iconv.conv( 'ISO-2022-JP', 'EUC-JP', mesg )

Net::SMTP.start( 'localhost', 25 ) do |smtp|
str = mail.encoded
smtp.send_mail( str, mail.from, mail.destinations )
end
end

# ログファイルからサイトID取得
busy_site_ary = get_log_site_list( interval, log_keyword )

# フラグファイル名からサイトID取得
flag_site_arys = Array.new
count = 1
while count <= alert_check_count flag_site_arys.push( get_flag_site_list( flag_dir, count ) ) count += 1 end

# 初期フラグ
first_flag_ary = busy_site_ary
flag_site_arys.each do |site_ary|
first_flag_ary = first_flag_ary - site_ary
end
prefix = make_prefix( 1 )
first_flag_ary.each do |site_id|
flag_file = flag_dir + prefix + site_id
system( '/bin/touch', flag_file )
if alert_check_count == 1
send_mail( mailto, host, site_id, "alert" )
end
end

# フラグ変更(削除)&メール送信
count = 1
flag_site_arys.each do |site_ary|
prefix = make_prefix( count )
if count < prefix_2 =" make_prefix(" flag_file =" flag_dir" flag_file_2 =" flag_dir" count ="="" flag_file =" flag_dir" count ="="" end ="="="">

0 件のコメント: