ログファイル監視 + イベントスクリプト@ruby

ログファイルを監視して、ある文字列が出力されたらイベントを発生させたかったので、rubyで監視スクリプトを書いたので紹介します。

“log”というファイルを”hoge”という文字列で監視したい場合の使い方。

$ ./monitor.rb log hoge
ファイルlog を文字列hoge で監視します

ここで、他のコンソールから

$ echo "1234hoge5678" >> log

とすると下記のように出力されて終了します。

*** MATCH : 1234hoge5678

ログによってはcronでローテーションされて切り詰められて、新しい空のファイルになることもあるので、 その場合は古いファイルを見ずに新しいファイルを見るような処理も入っています。

ファイル名 : monitor.rb
-------------------------
#!/usr/bin/ruby

def usage()
    puts "\nusage : ./monitor.rb filename string"
    puts "          filenameで指定されたファイルをstringで監視し、マッチすれば終了します"

end

if (ARGV[0].nil? || ARGV[1].nil?)
    puts "引数が足りません"
    usage()
    exit!
else
    begin
        filename = ARGV[0]
        file = File.open(filename, "r")
        filesize = File.size?(filename)
        if (filesize == nil)
            filesize = 0
        end
    rescue => e
        puts e
        puts filename + "を開くことができません"
        usage
        exit!
    end
    str = ARGV[1]
    puts "ファイル" + filename + " を文字列" + str + " で監視します"
end

#最終行まで移動
file.seek(0,IO::SEEK_END)

begin
    # 読み込みループ
    while (true) do
        line = file.gets()
        if (! line.nil?)
            if ( /#{str}/ =~ $_ )
                puts "*** MATCH : " + $_
                exit
            end
        else
            sleep(0.5)

            if ( ! File.exist?(filename))
                puts "ファイルが削除されました"
                file.close()
                exit!
            end

            newFilesize = File.size?(filename)
            if (newFilesize == nil)
                newFilesize = 0
            end
            if ($DEBUG)
                puts "oldsize : "+ filesize.to_s + " newsize : " + newFilesize.to_s
            end
            if (newFilesize < filesize)
                puts "ファイルが切り詰められました. 新しいファイルを読み込みます"
                file.close()
                begin
                    file = File.open(filename)
                rescue => e
                    puts e
                    puts "ファイルを再オープンできません"
                    exit!
                end
                file.seek(0,IO::SEEK_END)
            end
            filesize = newFilesize
        end
    end
ensure
    if (! file.closed?)
        file.close()
    end
    exit!
end
タイトルとURLをコピーしました