Syslogで障害通知機能を作る

INDEX PAGE


Syslogで障害通知機能を作る



Linux/Unixではsyslog機能を利用して
障害通知機能を実装するのが一般的だと思います。
http://ja.wikipedia.org/wiki/Syslog


私もこの方法で障害通知を実装しようと思い
ネットで調べていたところ、RubyにはSysLogクラスという便利なものがあるらしく
このクラスを利用すれば簡単に実装できそう!!
http://www.ruby-lang.org/ja/man/html/Syslog.html
と思ったのですが、とんでもない落とし穴が。。。。。。


なんと、このSyslogクラスはUNIX系のプラットフォームにしかAPIがなく
WindowsRubyにはAPIすら存在してない状況。
さらに言うと、プラットフォームごとにAPIも微妙に違うらしい。

と言うわけで、
(1).プラットフォームごとにSyslogラッパークラスを作成する
-別途、APIを保障する為に抽象スーパークラスを作成する(中身は空実装)
   プラットフォーム別のラッパークラスはすべてこのクラスを継承する。

class AbstractNotify

 ##プライオリティーフラグ(SubClassで定義する)
 INFO_MESSAGE = ''
 WARNING_MESSAGE = ''
 ERROR_NOTIFY = ''
 CRITICAL_NOTIFY = ''

 public
  ##初期化メソッド
  def initialize
  end

  ##終了メソッド
  def terminate
  end

  ##情報通知メソッド
  def notify( priority, message )
end

  -Windows版では単純に標準出力するのみの実装

class WindowsNotify < AbstractNotify

 public
  def initialize
   $stdout.print "障害通知クラスの初期化完了"
  end

  def terminate
   $stdout.print "障害通知クラスの完了"
  end

  def notify( priority, message )
   $stdout.print( message )
  end

end

  -Linux版では通常通りのSyslog出力を実装

require 'syslog'

class LinuxNotify < AbstractNotify

 ##プライオリティーフラグ
 INFO_MESSAGE = Syslog::LOG_INFO
 WARNING_MESSAGE = Syslog::LOG_WARNING
 ERROR_NOTIFY = Syslog::LOG_ERR
 CRITICAL_NOTIFY = Syslog::LOG_CRIT


  def initialize
   if Syslog.opend? then
    syslog = Syslog.reopen("HTTPD", Syslog::LOG_PID | Syslog::LOG_NDELAY,Syslog::LOG_DAEMON )
   else
    syslog = ("HTTPD", Syslog::LOG_PID | Syslog::LOG_NDELAY,Syslog::LOG_DAEMON )
   end
  end


  def terminate
   syslog.close
  end


  def notify( priority, message )
   syslog.log( priority, message )
  end

end

(2).障害通知アクセス用クラスを定義する。
    このクラスの中で(1)のクラスをインスタンス化して保持し障害通知処理を利用する。

NOTIFY_CLASS = 'WindowsNotify'
NOTIFY_FILE_PATH = 'windows_notify'

require 'abstract_notify'
require NOTIFY_FILE_PATH

class SyslogNotify

 ##メッセージ用定数
 INFO_MESSAGE_PREFIX = '[INFO]'
 WARNING_MESSAGE_PREFIX = '[WARNING]'
 ERROR_NOTIFY_PREFIX = '[ERROR]'
 CRITICAL_NOTIFY_PREFIX = '[CRITICAL]'

  def initialize
   ##Syslogの初期化
   @syslog = eval(NOTIFY_CLASS).new
  end

  def terminate
   ##Syslogのクローズ
   @syslog.terminate
  end


  def info_notify(message)
   @syslog.notify( eval(NOTIFY_CLASS)::INFO_MESSAGE, INFO_MESSAGE_PREFIX + message )
  end


  def warning_notify(message)
   @syslog.notify( eval(NOTIFY_CLASS)::WARNING_MESSAGE, WARNING_MESSAGE_PREFIX + message )
  end


  def error_notify(message)
   @syslog.notify( eval(NOTIFY_CLASS)::ERROR_MESSAGE, ERROR_NOTIFY_PREFIX + message )
  end


  def critical_notify(message)
   @syslog.notify( eval(NOTIFY_CLASS)::CRITICAL_MESSAGE, CRITICAL_NOTIFY_PREFIX + message )
  end

end


これを利用すれば、障害通知を利用するソースをいじることなく
「SyslogNotify」のソースを2行のみ環境に合わせて修正すれば利用が可能になります。
この2行については、環境ごとの定義をまとめたプロパティーなどを別途作っておいて利用するとより便利だと思います。

INDEX PAGE