Zabbix Conference 2012で登壇しました

先ほど、ヨーロッパから帰国しました。
いい機会をいただくことができ、今回、初めてZabbix Conferenceに参加しました。
しかも、20分の発表枠をいただくことができ、登壇までさせていただきました。

Zabbix Conferenceとは、
Zabbix SIAが主催する年1回のイベントです。
昨年に引き続き、今年が2回目の開催になります。

今年は、世界27カ国から156名の参加者が来られていたそうです。

Zabbixを活用した事例や、Zabbixの今後の最新ロードマップ等が発表されました。
そこで、1枠いただき、現在、自分自身が取り組んでいるZabbixを使ったハイブリッド環境管理のお話させていただくことができました。

資料はZabbixの公式ページでも公開されています。http://www.zabbix.com/conf2012_agenda.php
SlideShareにもアップしたので、こちらでもご覧いただけます。



Zabbix Conferenceへの参加レポートの詳細は、弊社の技術ブログ「http://tech-sketch.jp/」にて公開する予定ですので、
少々お待ち下さい。

初の海外出張で、英語の発表をするという自分にとっては少しハードルの高いことだったのですが、
沢山の方々のご協力により、無事終えることができました。
Zabbix SIAの寺島ご夫妻はじめ、皆様ありがとうございました。

発表後には沢山の方々にお声をかけていただいたのですが、
なかなかうまく英語で会話できず、その点だけは今回の心残りです。
海外の方も含めた技術者の方と交流するのは非常にいい刺激になりました。

Chromix Manual (English ver.)

Chromix

This tool is a Zabbix Trigger Check tool.
When Trigger is "PROBLEM", this tool generate Desktop Notification.

This tool uses Zabbix API.

You can register Multi Zabbix Servers to this tool.
So, when you manage many zabbix server, you may be happy.

I tested the following environments:
Zabbix Server
- ver.1.8.3
- ver.1.9.8
- ver.2.0.0RC2
- ver.2.0.0

Chrome
- 19.0.1084.41 beta-m
- 22.0.1229.14 beta

How to Use

1. Prior Work

This app is using Zabbix API,
So, you should give API access authority.

Zabbix 1.8:
Belong to "API access" group the users that you want to access.

Zabbix 2.0:
It is not necessary to the above work.
You just have to give access to the host to the user.

Please check the official document.
Zabbix documentation [Zabbix Documentation 4.0]

2. Installation

Please install the Chromix from the Chrome Web Store.
Chromix - Chrome Web Store

3. Registration of Zabbix info
  • Click Chromix icon on your chrome tool bar.
  • Click "Add Zabbix".
  • Fill in data about Zabbix.

If your Zabbix top url is "http://hostname/zabbix", the url column is filled in the box to this format "hostname/zabbix".
If your Zabbix use "https", please check "SSL?" box.


4. Check the trigger

After this configure, chromix start monitoring trigger which status is "problem" automatically .
(Number of list item is only 100.)

5. Background

Chromix count the number of problems that occurred up to the current time from the last check of chromix.
So, When you check the popup once, the number is reset.

6. Settings

At the chromix option page, you can set Desktop Notification feature.
If you want to use Desktop Notification function, Please Click "On".

At this page, you can also change Background check rate and Notification display time.
Default setting is 20 seconds.

Chrome Extensionのmanifestバージョンを上げる(1から2へ)

Chrome Extensionを更新しようとすると、Manifestバージョンを1から2にあげろといわれたので対応してみました。
今回対応したのは、Zabbixトリガーチェック用Chrome Extensionの「Chromix - Chrome Web Store」です。

そもそも今までmanifestバージョンを指定していなかったので、
まずmanifest.jsonに以下を追記します。
(指定しなかった場合は1とみなされるようです)

"manifest_version":2,

これで拡張機能をインストールしてみると、設定がおかしいとかでエラー。
browser_actionにbackground_pageの項目を設定していたが、この指定方法が変更になるらしい。

"background_page":"background.html"
↓
"background":{"page":"background.html"}

これでインストール時のエラーはでなくなったが、今度はbrowser_actionが動かない。
ここの記述方法も変更になっており、

"browser_action":{
  "popup":"popup.html"
}

↓

"browser_action":{
  "default_popup":"popup.html"
}

これでpopupはうまく表示されました。

すると次は、inlineで読み込んでいるJavaScriptが動作しない。
開発ツールのコンソールでエラーを確認すると、以下のエラーが発生。

Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".

セキュリティポリシーでブロックされているらしい。
ということで、これも修正。


の中に直接JavaScriptを書いていたところをすべて外だしのファイルにして、
src="js/xxx.js"という形で読み込むように修正。

これで修正してもまだエラーが発生。

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:".
 <a href="#" id="add" onclick="displayLoginBox()" tabindex="1">Add Zabbix</a>

aタグの中のonclickにJavaScriptを埋め込んでいた部分でもエラーが発生。
この部分はjQueryで処理できるように以下のようにJavaScriptファイルに書き換えて対応。

$("#add").click(function(){ displayLoginBox(); });

以上で問題なく動作するようになった。
inlineでの読み込みじゃなく、正しくJavaScript処理をファイルで分けていればmanifest.jsonの書き換えだけでなんとかなるのではないでしょうか。

最終的なmanifest.jsonはこんな感じになりました。

{
  "name":"Chromix",
  "version":"1.2",
  "manifest_version":2,
  "background":{"page":"background.html"},
  "description":"Zabbix Alert Check Extension",
  "options_page":"options.html",
  "permissions":[
    "notifications",
    "tabs",
    "http://*/*",
    "https://*/*"
   ],
  "browser_action":{
    "default_icon": "image/chromix_normal_icon.png",
    "default_popup":"popup.html"
  },
  "icons": {
    "16": "image/chromix_icon_16x16.png",
    "48": "image/chromix_icon_48x48.png",
    "128": "image/chromix_icon_128x128.png"
  }
}

ここに変更箇所が書かれているのでチェックしてください。
http://developer.chrome.com/extensions/manifestVersion.html

バージョン1はサポートされなくなるらしいので、version1で作成している人は修正が必要になるかと思います。

※2012/08/27追記

Desktop Notificationで画像アイコンを表示させていたのですが、
Manifestバージョンを2に上げた時から表示されなくなってしまいました。
http://developer.chrome.com/extensions/manifest.html#web_accessible_resources
ここの記述によると、web_accessible_resourcesという設定を追加して、
利用している画像ファイルをあらかじめ指定しておかないとパーミッションエラーで弾かれるようです。
ということで最終的にはこんな感じになりました。

{
  "name":"Chromix",
  "version":"1.5",
  "manifest_version":2,
  "background":{"page":"background.html"},
  "description":"Zabbix Alert Check Extension",
  "options_page":"options.html",
  "permissions":[
    "notifications",
    "tabs",
    "http://*/*",
    "https://*/*"
   ],
  "browser_action":{
    "default_icon": "image/chromix_normal_icon.png",
    "default_popup":"popup.html"
  },
  "icons": {
    "16": "image/chromix_icon_16x16.png",
    "48": "image/chromix_icon_48x48.png",
    "128": "image/chromix_icon_128x128.png"
  },
  "web_accessible_resources": [
    "image/chromix_error_icon.png",
    "image/chromix_normal_icon.png",
    "image/warning.png",
    "image/secure.ico"
  ]
}

Zabbixのテンプレート設定ページをハイライト

Zabbixで設定していて、テンプレートのアイテムを設定しているのか、ホストのアイテムを設定しているのか、たまに迷子になりませんか?
そんな方のために、テンプレートのページだけ色付けしてハイライトするUserScriptを作成してみました。

Zabbix2.0に対応した形で作りましたが、一応Zabbix1.8系でも動くようにしています。
ただ、場合によってはうまく動かないのでご了承下さい。
気休め程度に使ってもらえればと思います。

Zabbix1.8系とZabbix2.0系では画面デザインが大きく変わっていて、
2.0系の方が、わかりやすくなっています。
2.0系ならば普通に使っていてもわからなくなることはないかと思うので、
不要かもしれませんがご参考までにどうぞ。



使い方

zabbix_highlighter/highlight.user.js at master · ikd-work/zabbix_highlighter · GitHub
ここからhighlight.user.jsをダウンロードして下さい。

Chromeであれば、「ツール」→「拡張機能」で拡張機能のページを開き、そのページにダウンロードしたファイルをドラッグ&ドロップして下さい。

FireFoxであれば、Greasemonkeyを事前にインストールしておき、ブラウザにダウンロードしたファイルをドラッグ&ドロップして下さい。

あとは、http://・・・/zabbixまたはhttps://・・・/zabbixのページに行けば機能してくれるはずです。

うまく動かなかったらすいません。
Javascriptも無理矢理書いているので、かなり怪しいですが・・・

Zabbix Senderで複数の値を一括登録

Zabbixの非常に役に立つ機能として、
Zabbix Senderというものがあります。

これは、Zabbix Serverから定期的にポーリング監視するのではなく、
監視される側から値をZabbix Serverに対して送りつけることができる機能です。

Zabbix SenderはZabbix Agentをインストールことで合わせてインストールされます。

rpmパッケージでzabbix agentをインストールした場合には、/usr/bin/zabbix_senderというパスでzabbix_senderがインストールされます。

基本的な使い方

基本的な使い方としては以下のようになります。

$ zabbix_sender -z "zabbix serverホスト名orIP" -p "zabbix serverポート番号" -s "ホスト名" -k "キー名" -o "値"

例えば、10.1.1.1の10051ポートで稼働しているZabbix Serverに登録されている「test-server」というホストの「test.item」というキーのアイテムにデータを登録したい場合、以下のようにします。

$ zabbix_sender -z 10.1.1.1 -p 10051 -s test-server -k test.item -o 100

これで100という結果がtest.itemに登録されます。

監視対象機器の内部で何かしら処理させて取得できた結果を送りつけるのに非常に便利に利用できます。

注意点

この時、Zabbix Serverのtest.itemに登録されたデータの「時刻」はzabbix_senderが実行された時の現在時刻が登録されるようになっています。
そのため、例えば、過去の時点での監視結果を登録したい場合などに困ることになります。

具体的な例として、AWSのCloudWatchの結果をZabbixに連携したい場合を考えてみます。

AWSのCloudWatchの結果をAPIで取得してきた場合、以下のような値が取得できます。
詳しくはこちらより(http://docs.amazonwebservices.com/AmazonCloudWatch/latest/APIReference/API_GetMetricStatistics.html)

  • Average
  • Maximum
  • Minimum
  • SampleCount
  • Sum
  • Timestamp
  • Unit

これらの値が時間毎に配列として返ってきます。
「最新の値だけをZabbix Senderで送付する」という形でももちろんいいのですが、
実際のCloudWatchでの監視時刻とZabbixに登録された時刻が変わってしまいます。
CloudWatch APIで取得してきた結果の中に「Timestamp」があるので、
その時刻に合わせた形でZabbixにも登録したいと思います。
その時に役立つのが、zabbix_senderの-Tオプションです。

複数の値を正しい時刻で一括登録する

"-T"オプションを使って登録してみます。

"-T"オプションを使う場合には、登録したい内容をあらかじめファイルに記述しておいて読み込むか、標準入力から読み込む必要があります。
まずはファイルから読み込む場合の方法です。

ファイルの記述方法はこんな感じ

hostname key timestamp value
hostname key timestamp value
・・・以下、この繰返し

スペース区切りで1行に1データの情報を記述するといった感じです。
具体的にはこんな感じ

/tmp/sender_data.txt

test-server test.item 1340336274 aaa
test-server test.item 1340336214 bbb
test-server test.item 1340336154 ccc

timestampはunixtimeの形式で記述する必要があります。
そのため、例えば先に紹介したCloudWatchのAPI取得結果を登録したい場合には、
APIから取得できたTimestampをunixtimeに変換するといった処理が必要になります。
(Rubyで処理させる場合はTime.parseとか.to_iとか使えば簡単に変換可能です。)

zabbix_senderコマンドの実行形式は以下のようにします

$ zabbix_sender -z 10.1.1.1 -p 10051 -T -i /tmp/sender_data.txt

すると一回のzabbix_sender実行でsender_data.txtに記載した3件のデータを一括登録できます。

"-T"オプションを付けた場合は、zabbix_senderの引数として-sや-kをつけても無視され、ファイル内に記載したホスト名、キー名に対して登録処理がされます。

ファイル書き出しをしたくない場合は、以下のようにechoとかで標準出力した結果を入力とすることで、
同じ処理を行うことが可能です。

$ echo -n -e "test-server test.item 1340336274 aaa\ntest-server test.item 1340336214 bbb\ntest-server test.item 1340336154 ccc" | zabbix_sender -z 10.1.1.1 -p 10051 -T -i -

この機能をうまく使うことでZabbix Sender処理頻度を少なくでき、
監視負荷を抑えることができます。

ぜひ、活用してみてはいかがでしょうか。

ZabbixのWeb監視部分のソースコードを読んでみた

ZabbixにはWeb監視の機能があり、
シナリオに沿って、各ページのレスポンスコードや応答時間などの監視を行うことが可能です。

シナリオは例えば以下のような形で設定します。

ステップ1
 URL: http://hostname/login
 想定レスポンスコード: 200
 レスポンスに含まれるべき要求文字列: login page
 
ステップ2
 URL: http://hostname/auth
 想定レスポンスコード: 200
 レスポンスに含まれるべき要求文字列: ok

といった具合に設定していきます。
また、Basic認証が要求されるようなサイトの場合は、
シナリオに対して、User、Passwordを設定しておくことで認証後のページのチェックを行うことも可能です。

Web監視の機能で設定したURLをチェックした場合に、
もしリダイレクトされるとどういう挙動をするのかをソースコードから追ってみました。

Zabbixのソースコードのsrc/zabbix_server/httppoller/httptest.cにWeb監視処理が記述されています。

この中を見ると、Web監視にはlibcurl(http://curl.haxx.se/libcurl/)というライブラリを利用しているのがわかります。

libcurlについてはこちらのページに詳しく書かれているので参考にさせていただきました。
http://d.hatena.ne.jp/irasya/20090726/1248610519

・・・・略
if (NULL == (easyhandle = curl_easy_init()))
{
     err_str = zbx_strdup(err_str, "could not init cURL library");
     zabbix_log(LOG_LEVEL_ERR, "web scenario \"%s\" error: %s", httptest->name, err_str);
     goto clean;
}

if (CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_COOKIEFILE, "")) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_USERAGENT, httptest->agent)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1L)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_WRITEFUNCTION, WRITEFUNCTION2)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_HEADERFUNCTION, HEADERFUNCTION2)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYPEER, 0L)) ||
     CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_SSL_VERIFYHOST, 0L)))

・・・・略

     if (CURLE_OK != (err = curl_easy_getinfo(easyhandle, CURLINFO_RESPONSE_CODE, &stat.rspcode)))
     {

・・・・略

この辺りがlibcurlを利用している部分になります。

curl_easy_init()で初期化をし、
curl_easy_setopt()でcurlを実行する際のオプション設定を行なっています。
curl_easy_setopt()については上記部分だけではなく、シナリオのステップ設定に応じて追加設定するよう書かれています。

オプション設定が終了後、curl_easy_getinfoでレスポンスコードや処理時間などの値を取得しています。

この中でWeb監視の挙動を決めているcurl_easy_setoptについて詳しく見てます。

上記設定を見ると、まずデフォルトで以下のオプションを指定しているのがわかります。

  • CURLOPT_COOKIEFILE
  • CURLOPT_USERAGENT
  • CURLOPT_FOLLOWLOCATION
  • CURLOPT_WRITEFUNCTION
  • CURLOPT_HEADERFUNCTION
  • CURLOPT_SSL_VERIFYPEER
  • CURLOPT_SSL_VERIFYHOST

それぞれが何を意味しているのかはこちらのサイトが参考になりました。
http://curl.haxx.se/libcurl/c/curl_easy_setopt.html

リダイレクト先を見に行くかどうかに関係している設定は"CURLOPT_FOLLOWLOCATION"になります。
この設定をTrueにすることでレスポンスヘッダのLocation:部分をチェックして、その先まで見に行くようになります。

上で示したコード中では、

CURLE_OK != (err = curl_easy_setopt(easyhandle, opt = CURLOPT_FOLLOWLOCATION, 1L)) ||

このように設定され、有効に設定されています。
そのため、リダイレクト先の情報を見に行くようになっていることがわかります。

次に気になる点としては、何個先まで見に行くようになっているのかについてです。

この設定は、curl_easy_setoptで"CURLOPT_MAXREDIRS"で指定を行うようです。
Zabbixのソースコード中にはこの指定が存在していないため、
Locationを最後まで辿っていくようです。

実際に以下のような環境を作って試してみました。

http://hostname/top レスポンスコード:301
↓Redirect
http://hostname/next レスポンスコード:301
↓Redirect
http://otherhost/final レスポンスコード:403

このようなリダイレクトするサイトを用意し、
ZabbixのWeb監視でhttp://hostname/topを監視してみると、
取得できたレスポンスコードは最終的な403でした。

Web監視の挙動が気になる方はこういったポイントをチェックしてみてはいかがでしょうか?