Nagios中文顯示問(wèn)題的解決方案
Nagios的Status Map功能鏈接能夠顯示被監(jiān)控的網(wǎng)絡(luò)拓?fù)鋱D,并在節(jié)點(diǎn)圖片上面顯示節(jié)點(diǎn)設(shè)備名。遺憾的是,默認(rèn)的Nagios不支持中文。為此我研究了兩天Nagios以及GD的源代碼,終于找到了解決方案,詳述如下:
解壓縮Nagios中文源代碼包(以nagios-3.0.3為例),實(shí)現(xiàn)繪制網(wǎng)絡(luò)拓?fù)鋱D的源代碼文件是nagios-3.0.3/cgi/statusmap.c,編譯安裝后,這個(gè)文件對(duì)應(yīng)nagios/sbin/statusmap.cgi,當(dāng)你在Nagios中文運(yùn)行界面點(diǎn)擊左側(cè)的“Status Map”鏈接時(shí),服務(wù)器(apache、tomcat等支持CGI的服務(wù)器軟件)調(diào)用可執(zhí)行文件statusmap.cgi,實(shí)現(xiàn)在瀏覽器客戶區(qū)中繪制網(wǎng)絡(luò)拓?fù)鋱D。
statusmap.c中負(fù)責(zé)繪制節(jié)點(diǎn)設(shè)備名的函數(shù)是void draw_text(char *buffer,int x,int y,int text_color),就在本文件中定義,它調(diào)用GD的一個(gè)庫(kù)函數(shù)——
gdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color);來(lái)繪制節(jié)點(diǎn)設(shè)備名。
這里先簡(jiǎn)單介紹一下GD以及其他一些軟件與Nagios的關(guān)系。Nagios處理圖片(包括繪制文字)需要借助于GD,有些版本的Linux已經(jīng)集成了GD,所以可以直接安裝使用Nagios。安裝GD以及相關(guān)的軟件包的順序如下(版本僅為舉例):
gd:一個(gè)處理圖片(包括繪制文字)的軟件包;
freetype:gd解析字庫(kù)用到的軟件包;
libpng:gd解析png圖片用到的軟件包;
jpeg:gd解析jpeg圖片用到的軟件包。
安裝方法舉例:
安裝方法
安裝freetype
#cd /data/software
#tar xzvf freetype-2.1.5.tar.gz
#cd freetype-2.1.5
#./configure --prefix=/usr/local/modules/freetype
#make
#make install
安裝libpng
#cd /data/software
#tar xzvf libpng-1.2.5.tar.gz
#cd libpng-1.2.5
#cp scripts/makefile.std makefile \\不要用--prefix自定義安裝目錄,影響gd的安裝
#make
#make install
安裝jpeg
#mkdir /usr/local/modules/jpeg6
#mkdir /usr/local/modules/jpeg6/bin
#mkdir /usr/local/modules/jpeg6/lib
#mkdir /usr/local/modules/jpeg6/include
#mkdir /usr/local/modules/jpeg6/man
#mkdir /usr/local/modules/jpeg6/man/man1
#cd /data/software
#tar xzvf jpegsrc.v6b.tar.gz
#./configure --prefix=/usr/local/modules/jpeg6 --enable-shared --enable-static
#make
#make install
安裝gd
#cd /data/software
#tar xzvf gd-2.0.33.tar.gz
#./configure --prefix=/usr/local/modules/gd --with- jpeg=/usr/local/modules/jpeg6 --with-png --with-zlib --with-freetype=/usr/local/modules/freetype
#make
#make install
最后,在安裝nagios時(shí)#./configure步驟加一組參數(shù):--with-gd-lib=/usr/local/modules/gd/lib
原始的Nagios中文版不能繪制中文字符串,與GD的字庫(kù)處理方式有關(guān)。GD有自己的字庫(kù)文件(點(diǎn)陣形式、ASC碼編碼)。gdImageString的第二個(gè)參數(shù)即GD自己的字庫(kù)的索引,第五個(gè)參數(shù)則是一個(gè)ASC編碼的字符串。而GD自己的字庫(kù)是不支持中文的。顯然,大名鼎鼎的GD不可能只支持自己的字庫(kù),他用函數(shù)gdImageStringFT來(lái)支持用外部字庫(kù)繪制utf-8編碼的字符串,這里面包含了中文的支持。
gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,double ptsize, double angle, int x, int y, char *string),函數(shù)名中的“FT”就是freetype的意思,這個(gè)函數(shù)通過(guò)調(diào)用freetype包,支持解析.ttf格式(ttf是TrueType Font的縮寫)的字庫(kù)文件,只要找到Linux下的中文字庫(kù)的位置,作為第四個(gè)參數(shù)傳給該函數(shù),并且保證char *string是utf-8編碼,就能順利繪制中文字符串。在我的調(diào)試環(huán)境下,修改如下:
原函數(shù):
gdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color);
修改后:
gdImageStringFT(map_image,&brect[0],text_color,"/usr/share/fonts/zh_CN/TrueType/gbsn00lp.ttf",10,0.0,x-(string_width/2),y-(2*string_height),buffer);
(gdImageString和gdImageStringFT詳細(xì)的功能和參數(shù)說(shuō)明見GD安裝包下的說(shuō)明文檔index.html)
由于Nagios是從配置文件中讀取設(shè)備名字符串然后繪制到屏幕上,所以如果配置文件本身是utf-8編碼,如上修改后,重裝Nagios就可以順利顯示了。如果配置文件不是utf-8,那么可以通過(guò)兩種方法解決:
第一種:將配置文件轉(zhuǎn)成utf-8編碼。這樣不用再度修改源碼,但個(gè)人不贊成這種方法,理由是:由于Nagios的CGI是用C寫的,而C是基于ASC編碼的,Nagios又沒(méi)有借助第三方數(shù)據(jù)庫(kù),而是依賴于讀寫自己創(chuàng)建的大量配置文件和日志文件,其中用到很多基于ASC編碼的字符串處理函數(shù),雖然都是英文的,而英文的ASC編碼和utf-8完全相同,但是如果將Nagios的相關(guān)文件都轉(zhuǎn)成utf-8編碼,可能會(huì)導(dǎo)致一些潛在的問(wèn)題。
第二種:在gdImageStringFT之前加一個(gè)字符串編碼轉(zhuǎn)換函數(shù),將讀入的非utf-8編碼字符串buffer轉(zhuǎn)換成utf-8編碼,再傳給gdImageStringFT處理。這樣的字符串編碼轉(zhuǎn)換函數(shù)網(wǎng)上有很多資源,在此限于篇幅不詳述。
【編輯推薦】