zabbix 1.4.1 におけるログ監視について

初めまして。

zabbix 1.4.1 での監視設定時における
以下の現象について質問させて下さい。

ログの監視設定(例えば log[/var/log/messages] など)時に、
監視対象のログに文字数の多い行(半角2万文字位)が含まれていると、
その行の取得時に zabbix_agentd のプロセスが死んでしまう。

この現象は、zabbix 1.1.6 では起きなかった。(2万文字位でもOKだった)

以上について情報をお持ちの方、宜しくお願い致します。

コメント表示オプション

お好みのコメント表示方法を選び「設定の保存」をクリックすると変更が反映されます。
ユーザー KAZ の写真

はじめまして、KAZと申します。

zabbix1.4.2で試してみました。
1行が2万文字のログをzabbix agent(active)でアイテム追加したらzabbix_agentdが下記のログを出力してダウンしました。
20409:20070914:125841 One child process died. Exiting ...
20409:20070914:125841 zbx_on_exit() called.
20410:20070914:125841 Got signal. Exiting ...
20412:20070914:125841 Got signal. Exiting ...
20413:20070914:125841 Got signal. Exiting ...
20414:20070914:125841 Got signal. Exiting ...
20409:20070914:125843 ZABBIX Agent stopped

デバック文を入れて追ってみたところ下記のルートで動いていました。
active.c process_active_check関数
 ↓
active.c send_value関数
 ↓
comms.c comms_create_request関数の58行目でダウン

メモリ破壊でも起こしているのでしょうか…

ユーザー KAZ の写真

KAZです。

どうやらbase64にencode時に領域破壊を起こしているようです。
取り合えず変換先の領域サイズ分のみencodeするように変更したらダウンしなくなりました。

zabbix-1.4.2/src/libs/zbxcommon/comms.c comms_create_request関数

変更前:str_base64_encode(var, data_b64, (int)strlen(var)); \
変更後:str_base64_encode(var, data_b64, (int)strlen(var) > ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3 : (int)strlen(var)); \

以上

ユーザー ysm の写真

ysmです。

返信遅くなりました。
情報有難う御座います。

encode用のバッファがオーバーフローしている様ですね。
ご教授戴いた方法を試してみようと思います。

ユーザー shige の写真

お世話になっております。

>監視対象のログに文字数の多い行(半角2万文字位)が含まれていると、その行の取得時に zabbix_agentd のプロセスが死んでしまう。

上記ですが、監視対象がWindows環境でも同様の現象が起きてしまいます。対処法をご存知であればご教示いただければと思います。

ZABBIXのバージョンは[1.4.5]です。

以上、よろしくお願い致します。

ユーザー KAZ の写真

始めまして、shigeさん
KAZと申します。

ソースを確認しましたが1.4.5でも修正されていないようです。
下記の通り修正し、コンパイルすれば取り敢えず落ちなくはなります。(但し、はみ出した分のデータを切り落としてしまいます…)

zabbix-1.4.5/src/libs/zbxcommon/comms.c comms_create_request関数

変更前:str_base64_encode(var, data_b64, (int)strlen(var)); \
変更後:str_base64_encode(var, data_b64, (int)strlen(var) > ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3 : (int)strlen(var)); \

ユーザー shige の写真

KAZさん

ご返信ありがとうございます。
shigeです。

下記の処方を適用してみました、Linuxのエージェントに関しては、動作するようになりましたが、Windows用のエージェントでは再現してしまいます。

Windows用のエージェントには、別の処方があるのでしょうか?

以上、よろしくお願い致します。

KAZさんは書きました:
始めまして、shigeさん
KAZと申します。

ソースを確認しましたが1.4.5でも修正されていないようです。
下記の通り修正し、コンパイルすれば取り敢えず落ちなくはなります。(但し、はみ出した分のデータを切り落としてしまいます…)

zabbix-1.4.5/src/libs/zbxcommon/comms.c comms_create_request関数

変更前:str_base64_encode(var, data_b64, (int)strlen(var)); \
変更後:str_base64_encode(var, data_b64, (int)strlen(var) > ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3 : (int)strlen(var)); \

ユーザー KAZ の写真

すいません、手元にzabbixの検証に使えるwindows機がなく…
只、zabbix_agentd.cのmain関数〜comms.cのcomms_create_request関数迄のソースをざっと見ましたが問題ないかと…

windowsのagentでdebugレベルのログを出力させる事は可能でしょうか?可能でしたらエラー時のログを見せて頂けると何かしら分かるかもしれません。

ユーザー shige の写真

KAZさん

お世話になっております。

Windows環境でDebugLevel=5で起動した際のログ以下に添付します。
以上、宜しくお願いします。

【zabbix_agentd.log】
-------------------------------------------------------------
3456:20080624:220448 zabbix_agentd started. ZABBIX 1.4.5.
3624:20080624:220448 zabbix_agentd collector started
3824:20080624:220448 zabbix_agentd listener started
3624:20080624:220448 In GetCounterName() [index:6]
3804:20080624:220448 zabbix_agentd listener started
1456:20080624:220448 zabbix_agentd listener started
3400:20080624:220448 zabbix_agentd active check started [10.110.5.172:10051]
3400:20080624:220448 In init_active_metrics()
3400:20080624:220448 In refresh_metrics('10.110.5.172',10051)
3400:20080624:220448 get_active_checks('10.110.5.172',10051)
3400:20080624:220448 Sending [ZBX_GET_ACTIVE_CHECKS
rmc-ssp-12
]
3400:20080624:220448 Before read
3400:20080624:220448 In parse_list_of_checks() [log[c:\2man]:300:0
ZBX_EOF
]
3400:20080624:220448 In disable_all_metrics()
3400:20080624:220448 Parsed [log[c:\2man]:300:0]
3400:20080624:220448 In add_check('log[c:\2man]', 300, 0)
3400:20080624:220448 Parsed [ZBX_EOF]
3400:20080624:220448 In process_active_checks('10.110.5.172',10051)
3400:20080624:220448 In process log (c:\2man,0)
------------------------------------------------------------

ユーザー KAZ の写真

shigeさん

KAZです。
ログを見るあたり、同じ位置で落ちているように見えます…

実は私、zabbixをWindowsでBuildした事がなく、本日Visual Studio 2008を入れてBuildをしてみたのですが、エラーがでて上手くBuildできませんでした。

shigeさんの方でWindowsで上手くBuildできるならば、お恥ずかしいですが構成を教えて頂けませんでしょうか…

ユーザー tsuzuki の写真

はじめまして。
tsuzukiです。

私のビルド方法でよければ、以下のようにやってますので参考にしてください。
つっこみも大歓迎です。

Zabbix の開発者は windows 版を Visual Studio 2005 でコンパイルしているようだったので、VS2005でやってみました。
参考(2007/01/11時点):
http://www.zabbix.com/forum/showthread.php?t=5711&highlight=compile&page=2

#############################################################################################################
1.) Visual C++ 2005 Express Edition をインストール。
http://www.microsoft.com/japan/msdn/vstudio/express/maninstall/
2.) winsock2.h を使用しているので Microsoft Platform SDK をインストール。
コンパイル環境の OS が 32bit ならば、PSDK-x86.exe を選択。
http://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en
3.) Microsoft Platform SDK インストール後、 Visual Studio 2005 へ、バイナリ、インクルード、ライブラリのパスを追加。
ウィンドウのトップより、「ツール」-「オプション」-「プロジェクトおよびソリューション」-「VC++ ディレクトリ」
-「実行可能ファイル」に以下パスを追加。
C:\Program Files\Microsoft Platform SDK\Bin
C:\Program Files\Microsoft Platform SDK\Bin\winnt
ウィンドウのトップより、「ツール」-「オプション」-「プロジェクトおよびソリューション」-「VC++ ディレクトリ」
-「インクルードファイル」に以下パスを追加。
C:\Program Files\Microsoft Platform SDK\Include
C:\Program Files\Microsoft Platform SDK\Include\mfc
ウィンドウのトップより、「ツール」-「オプション」-「プロジェクトおよびソリューション」-「VC++ ディレクトリ」
-「ライブラリファイル」に以下パスを追加。
C:\Program Files\Microsoft Platform SDK\Lib
4.) build/win32/include/config.h で include/config.h を置換。
5.) src/libs/zbxsys/threads.c の76行目のコメント内の不正文字を削除して保存。(コンパイル時にこのロケールだと読めない!って怒られてしまってました)
6.) build/win32/project/ZABBIX.sln から Visual Studio 2005 を起動。
7.) 各プロジェクトのプロパティより、「リンカ - 入力 - 追加の依存ファイル」に「advapi32.lib」を追加。
8.) 「Release」、「Win32」を選択してソリューション全体をビルド。おそらく、依存関係に関連して zabbix_get はエラー
となるが、再度ビルドすることでビルドに成功。
#############################################################################################################

==========================================================
Takanori Suzuki あっと MIRACLE LINUX
==========================================================

ユーザー KAZ の写真

tsuzukiさん、始めましてKAZと申します。

情報提供ありがとうございます。
コンパイルできました。

ユーザー KAZ の写真

shigeさん

当方でもdebug文を加えてbuildし実行してみました。
対象ファイルの1行の長さは24000文字(半角)
※:IPアドレスやホスト名は伏字にしております。

明日、もう一度情報を詳細に取れるようなdebug文を入れて試して見ます。

1504:20080626:193809 zabbix_agentd started. ZABBIX 1.4.5.
264:20080626:193809 zabbix_agentd collector started
252:20080626:193809 zabbix_agentd listener started
916:20080626:193809 zabbix_agentd listener started
1520:20080626:193809 zabbix_agentd listener started
676:20080626:193809 zabbix_agentd active check started [xxx.xxx.xxx.xxx:10051]
264:20080626:193809 In GetCounterName() [index:6]
676:20080626:193809 In init_active_metrics()
676:20080626:193809 In refresh_metrics('xxx.xxx.xxx.xxx',10051)
676:20080626:193809 get_active_checks('xxx.xxx.xxx.xxx',10051)
676:20080626:193809 Sending [ZBX_GET_ACTIVE_CHECKS
xxxxxxxx
]
676:20080626:193809 Before read
676:20080626:193809 In parse_list_of_checks() [log[d:\zabbix\TEST.txt]:30:28
ZBX_EOF
]
676:20080626:193809 In disable_all_metrics()
676:20080626:193809 Parsed [log[d:\zabbix\TEST.txt]:30:28]
676:20080626:193809 In add_check('log[d:\zabbix\TEST.txt]', 30, 28)
676:20080626:193809 Parsed [ZBX_EOF]
676:20080626:193809 In process_active_checks('xxx.xxx.xxx.xxx',10051)
676:20080626:193809 In process log (d:\zabbix\TEST.txt,28)
264:20080626:193809 In GetCounterName() [index:238]
264:20080626:193809 In GetCounterName() [index:6]
264:20080626:193809 In GetCounterName() [index:238]
264:20080626:193809 In GetCounterName() [index:6]
264:20080626:193809 In GetCounterName() [index:238]
264:20080626:193809 In GetCounterName() [index:44]
264:20080626:193809 In GetCounterName() [index:2]

ユーザー KAZ の写真

shigeさん

分かりました。
str_base64_encodeでデータ終端に'\0'を付加してるのですがされで1バイトメモリ破壊してました。

なので、base64 encode時の領域破壊対応は以下の通りです。

〜/src/libs/zbxcommon/comms.c comms_create_request関数

変更前:str_base64_encode(var, data_b64, (int)strlen(var)); \
変更後:str_base64_encode(var, data_b64, (int)strlen(var) > ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3 : (int)strlen(var)); \

〜/src\libs\zbxcrypto\base64.c str_base64_encode関数

変更前:for ( i = 0; i < in_size ; i += 3 )
変更後:for ( i = 0; i < in_size - 3 ; i += 3 )

尚、当方の検証した環境構成は以下の通り。
server CentOS4.4 :zabbix1.4.2
agent WindowsXP SP3:zabbix1.4.5

WindowsのBuildはVisual Studio 2005を使用。

以上

ユーザー kodai の写真

おぉ、すばらしいです!

このパッチを本家にも投稿していただくことはできないでしょうか?

本家の修正&リリースが遅くなるようだったら、暫定的にZABBIX-JPでパッケージ作成&公開を考えても良いかもしれません。

ユーザー KAZ の写真

お疲れ様です、kodaiさん。

このパッチを本家にも投稿していただくことはできないでしょうか?

本家の修正&リリースが遅くなるようだったら、暫定的にZABBIX-JPでパッケージ作成&公開を考えても良いかもしれません。

パッチを作るのはかまわないですが、あくまでzabbix_agentdを落ちないようにするだけの暫定対応でしかない代物なので…

本来は収集したログデータを切り捨てず、zabbix serverに分割送信するのが正しい仕様ではないかと…

一応以前も分割送信できないか考えたのですが、ちょっと手におえませんでした。多分send_value関数でencodeとsendしてるところをloopさせればいいんじゃないかと思うんですけど…

暫定版と言う扱いでよければパッチ作りますが、どうでしょう?

ユーザー KAZ の写真

KAZです。

本家に[1.4.x] PATCH: base64 encodingでアップしてきました。
英語の文章がかなり変な気がしますが…

ユーザー KAZ の写真

本日、分かったのですが、前回のpatchでは1行のログが短い時に上手く動作しない(ログが収集されない)ことが判明。

調べた結果、〜/src\libs\zbxcrypto\base64.c str_base64_encode関数の修正がまずかったみたいです。

結局〜/src/libs/zbxcommon/comms.c comms_create_request関数のみ下記のように修正して何とか事象が収まりました。

変更前:str_base64_encode(var, data_b64, (int)strlen(var)); \
変更後:str_base64_encode(var, data_b64, (int)strlen(var) > ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3-3: (int)strlen(var)); \

本家の方には明日パッチを作って送ろうかと思います。

ユーザー KAZ の写真

WindowsXPとCentOS4.xで確認を一通り取ってみました。

パッチは以下のものになります。
<code>
diff -Nur zabbix-1.4.2.orig/src/libs/zbxcommon/comms.c zabbix-1.4.2/src/libs/zbxcommon/comms.c
--- zabbix-1.4.2.orig/src/libs/zbxcommon/comms.c 2007-08-21 04:22:23.000000000 +0900
+++ zabbix-1.4.2/src/libs/zbxcommon/comms.c 2008-07-10 19:16:10.000000000 +0900
@@ -46,7 +46,7 @@
{
#define ADD_XML_DATA(tag_name, var) \
data_b64[0] = '\0'; \
- str_base64_encode(var, data_b64, (int)strlen(var)); \
+ str_base64_encode(var, data_b64, (int)strlen(var) >= ZBX_MAX_B64_LEN/4*3 ? ZBX_MAX_B64_LEN/4*3-3 : (int)strlen(var)); \
request = zbx_strdcatf(request, "<" tag_name ">%s</" tag_name ">", data_b64)

char data_b64[ZBX_MAX_B64_LEN];
</code>