天天看點

如何編寫 Nagios 插件 (http://zener.blog.51cto.com/937811/727685)

如何編寫 Nagios 插件

Nagios 的最激動人心的方面是可以輕松地編寫您自己的插件,隻需要了解一些簡單的指導原則即可。為了管理插件,Nagios 每次在查詢一個服務的狀态時,産生一個子程序,并且它使用來自該指令的輸出和退出代碼來确定具體的狀态。退出狀态代碼的含義如下所示:

  • OK —退出代碼 0—表示服務正常地工作。
  • WARNING —退出代碼 1—表示服務處于警告狀态。
  • CRITICAL —退出代碼 2—表示服務處于危險狀态。
  • UNKNOWN —退出代碼 3—表示服務處于未知狀态。

最後一種狀态通常表示該插件無法确定服務的狀态。例如,可能出現了内部錯誤。

下面提供了一個 Python 示例腳本,用于檢查 UNIX® 平均負載。它假定 2.0 以上的級别表示警告狀态,而 5.0 以上的級别表示危險狀态。這些值都采用了寫死的方式,并且始終使用最近一分鐘的平均負載。

清單 5. Python 插件—示例工作插件

#!/usr/bin/env python  import os,sys  (d1, d2, d3) = os.getloadavg()  if d1 >= 5.0:     print "GETLOADAVG CRITICAL: Load average is %.2f" % (d1)     sys.exit(2) elif d1 >= 2.0:     print "GETLOADAVG WARNING: Load average is %.2f" % (d1)     sys.exit(1) else:     print "GETLOADAVG OK: Load average is %.2f" % (d1)     sys.exit(0)      

在編寫了這個小的可執行插件之後,接下來是使用 Nagios 注冊該插件,并建立一個檢查平均負載的服務定義。

這項工作也是非常簡單的:使用下面的内容建立一個名為 ​

​/etc/nagios-plugins/config/mygetloadavg.cfg​

​ 的檔案,根據下面的示例,向 ​

​services.cfg​

​ 檔案添加一個服務。請記住,必須在 ​

​hosts.cfg​

​ 配置檔案中定義 ​

​localhost​

​。

清單 6. 示例插件—使用 Nagios 進行注冊

define command{         command_name    check_mygetloadavg  command_line    /path/to/check_getloadavg   }      

清單 7. 建立一個使用示例插件的服務

define service{         use                             service-template         host_name                       localhost         service_description             LoadAverage         check_period                    24x7         contact_groups                  server-admins         notification_options            c,r         check_command                   check_mygetloadavg         }      

編寫一個完整的插件

前面的示例說明了一個采用“寫死”方式插件的限制,它不支援運作時配置。在實際中,通常最好的方式是建立一個可配置的插件。通過這種方式,您可以建立和維護一個插件,使用 Nagios 将其注冊為單個插件,并且傳遞參數以便為特定的情況自定義警告和危險水準。下一個示例還包括一則使用消息;經過證明,對于由幾個不同的開發人員或者管理者所使用或維護的插件,這是非常有價值的。

另一個好的實踐是捕獲所有的異常,并後退以報告 UNKNOWN 服務狀态,以便 Nagios 能夠正确地管理有關這個情況的通知。那些允許異常“失敗”的插件通常會退出,并傳回值 1;對于 Nagios,這表示一個 WARNING 狀态。請確定您的插件能夠正确地區分 WARNING 和 UNKNOWN。請注意,例如,在将其作為 UNKNOWN 結果處理可能出現錯誤的情況下,通常可以禁用至少某些 WARNING 通知。

用 Python 編寫一個插件

上述的建議—運作時參數化、一則使用消息,以及經過改進的異常處理—将得到示例插件的源代碼,這段代碼要比前面的長幾倍。但是您可以更安全地對錯誤進行處理,并且能夠在更廣泛的範圍内重用該插件。

清單 8. Python 插件—擷取平均負載的完整插件

#!/usr/bin/env python  import os import sys import getopt  def usage():     print """Usage: check_getloadavg [-h|--help] [-m|--mode 1|2|3] \     [-w|--warning level] [-c|--critical level]"  Mode: 1 - last minute ; 2 - last 5 minutes ; 3 - last 15 minutes" Warning level defaults to 2.0 Critical level defaults to 5.0"""     sys.exit(3)  try:     options, args = getopt.getopt(sys.argv[1:],         "hm:w:c:",         "--help --mode= --warning= --critical=",         ) except getopt.GetoptError:     usage()     sys.exit(3)  argMode = "1" argWarning = 2.0 argCritical = 5.0  for name, value in options:     if name in ("-h", "--help"):         usage()     if name in ("-m", "--mode"):         if value not in ("1", "2", "3"):             usage()         argMode = value     if name in ("-w", "--warning"):         try:             argWarning = 0.0 + value         except Exception:             print "Unable to convert to floating point value\n"             usage()     if name in ("-c", "--critical"):         try:             argCritical = 0.0 + value         except Exception:             print "Unable to convert to floating point value\n"             usage()  try:     (d1, d2, d3) = os.getloadavg() except Exception:     print "GETLOADAVG UNKNOWN: Error while getting load average"     sys.exit(3)  if argMode == "1":     d = d1 elif argMode == "2":     d = d2 elif argMode == "3":     d = d3  if d >= argCritical:     print "GETLOADAVG CRITICAL: Load average is %.2f" % (d)     sys.exit(2) elif d >= argWarning:     print "GETLOADAVG WARNING: Load average is %.2f" % (d)     sys.exit(1) else:     print "GETLOADAVG OK: Load average is %.2f" % (d)     sys.exit(0)      

為了使用這個新的插件,需要使用下面的方法來注冊 ​

​/etc/nagios-plugins/config/mygetloadavg2.cfg​

​:

清單 9. Python 插件—使用 Nagios 進行注冊

define command{         command_name    check_mygetloadavg2   command_line    /path/to/check_getloadavg2 -m $ARG1$ -w $ARG2$ -c $ARG3$  }      

另外,根據下面的示例,在 ​

​services.cfg​

​ 檔案中添加或者更改服務條目。請注意,使用感歎号 ​

​!​

​ 來分隔插件參數。與前面一樣,必須在 ​

​hosts.cfg​

​localhost​

清單 10. 建立一個使用 Python 插件的服務

define service{         use                             service-template         host_name                       localhost         service_description             LoadAverage2         check_period                    24x7         contact_groups                  server-admins         notification_options            c,r         check_command                   check_mygetloadavg2!1!3.0!6.0         }      

用 Tcl 編寫一個插件

最後的示例是使用 Tcl 編寫的一個插件,它使用簡單對象通路協定 (SOAP) 和 Web 服務描述語言 (WSDL) 檢查 xmenthods.net 的匯率。SOAP 為該插件提供了匯率的目前值,并将這些值與配置的範圍進行比較。如果該值不屬于警告的範圍,那麼它将被認為是 OK。如果該值大于或者小于警告級别,但是并沒有超過危險極限,則将狀态設定為 WARNING。否則将其設定為 CRITICAL,除非出現了網絡錯誤,在這種情況下将狀态設定為 UNKNOWN。

該插件可以識别不同的可配置參數,以便能夠檢查不同範圍的匯率。它還可以用于檢查各個國家的各種匯率。

清單 11. Tcl 插件—驗證目前匯率

#!/usr/bin/env tclsh  # parse arguments package require cmdline set options {     {country1.arg "" "Country 1"}     {country2.arg "" "Country 2"}     {lowerwarning.arg "" "Lower warning limit"}     {upperwarning.arg "" "Upper warning limit"}     {lowercritical.arg "" "Lower critical limit"}     {uppercritical.arg "" "Upper critical limit"} }  array set opt [cmdline::getoptions argv $options {: [options]}]  # if the user did not supply all arguments, show help message for each necessary [array names opt] {     if {$opt($necessary) == ""} {         set argv "-help"         catch {cmdline::getoptions argv $options {: [options]}} usage   puts stderr $usage         exit 3     } }  # load TclWebServices package package require WS::Client  if {[catch {     # download WSDL     WS::Client::GetAndParseWsdl \         http://www.xmethods.net/sd/2001/CurrencyExchangeService.wsdl \  {} currency      # create stub commands     WS::Client::CreateStubs currency      # download the actual exchange rate     set result [lindex \         [currency::getRate "England" "Japan"] 1] } error]} {     # if downloading the rate failed for some reason, report it     puts "EXCHANGERATE UNKNOWN: $error"     exit 3 }      if {($result < $opt(lowercritical)) || ($result > $opt(uppercritical))} {     puts "EXCHANGERATE CRITICAL: rate is $result"     exit 2 } if {($result < $opt(lowerwarning)) || ($result > $opt(upperwarning))} {     puts "EXCHANGERATE WARNING: rate is $result"     exit 1 } puts "EXCHANGERATE OK: rate is $result" exit 0      

現在,您需要注冊這個指令,以便 Nagios 知道如何調用它。為了完成這項工作,可以使用與前面類似的配置和指令定義來建立一個名為 ​

​/etc/nagios-plugins/config/exchangerate.cfg​

​ 的檔案:

command_line    /path/to/check_exchangerate -country1 $ARG1$ -country2 $ARG2$ -lowercritical \  $ARG3$ -lowerwarning $ARG4$ -upperwarning $ARG5$ -uppercritical $ARG6$      

在下面的示例中,假定該指令的名稱為 ​

​check_exchangerate​

接下來,建立一個使用剛剛建立的插件來監視匯率的服務。下面是服務定義,它将該服務與 ​

​localhost​

​ 伺服器關聯起來。盡管這個檢查并不真正地關聯于任何實體主機,但是需要将它綁定到一台主機。如果這個檢查涉及到調用受信任的網絡中的伺服器的 SOAP 方法,那麼您可以添加需要進行監視的實際伺服器,并且在這個示例中,應該将服務綁定到該伺服器。清單 12 中的代碼檢查 英鎊對日元的匯率,并驗證匯率位于 225 到 275 之間。

清單 12. 添加 Tcl 插件作為一個新的服務

define service{         use                             service-template         host_name                       localhost         service_description             EXCHANGERATE         check_period                    24x7         contact_groups                  other-admins         notification_options            c,r         check_command                   check_exchangerate!England!Japan!200!225!275!300         }      

結束語