|
Nagios的Status Map功能链接能够显示被监控的网络拓扑图,并在节点图片上面显示节点设备名。遗憾的是,默认的Nagios不支持中文。为此我研究了两天Nagios以及GD的源代码,终于找到了解决方案,详述如下: 解压缩Nagios中文源代码包(以nagios-3.0.3为例),实现绘制网络拓扑图的源代码文件是nagios-3.0.3/cgi/statusmap.c,编译安装后,这个文件对应nagios/sbin/statusmap.cgi,当你在Nagios中文运行界面点击左侧的“Status Map”链接时,服务器(apache、tomcat等支持CGI的服务器软件)调用可执行文件statusmap.cgi,实现在浏览器客户区中绘制网络拓扑图。 statusmap.c中负责绘制节点设备名的函数是void draw_text(char *buffer,int x,int y,int text_color),就在本文件中定义,它调用GD的一个库函数——7 V3 |: M- r/ b0 B4 L2 [* M; J
gdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color);来绘制节点设备名。 这里先简单介绍一下GD以及其他一些软件与Nagios的关系。Nagios处理图片(包括绘制文字)需要借助于GD,有些版本的Linux已经集成了GD,所以可以直接安装使用Nagios。安装GD以及相关的软件包的顺序如下(版本仅为举例):: [, _$ M+ r- s/ z7 p6 t
gd:一个处理图片(包括绘制文字)的软件包;
9 o6 r9 B# E% a# G6 Dfreetype:gd解析字库用到的软件包;
$ \+ l A% u( }% I! w, wlibpng:gd解析png图片用到的软件包;
& m' k6 L S( l+ @jpeg:gd解析jpeg图片用到的软件包。 安装方法举例: 安装方法
3 o% O- b% l( `. A% f C安装freetype
3 ?7 R. J3 x& v; g, t#cd /data/software' t) I5 n" L1 B
#tar xzvf freetype-2.1.5.tar.gz. Z' |, q1 s/ S0 o& i; v" m. K" z' F- y
#cd freetype-2.1.5
4 Y B( A7 ]$ O9 M" B* Y# y* }#./configure --prefix=/usr/local/modules/freetype) }8 Q1 x2 K4 P2 B/ F9 K6 M% y
#make: m; I8 @! @# Y! t7 K2 i8 U; T! p
#make install 安装libpng" e8 }# N) P# [/ a. z: @
#cd /data/software
1 m* [- N8 k4 m U* N) B& ~/ ~& P& y#tar xzvf libpng-1.2.5.tar.gz
* l9 o- w& Y3 ]0 U, \+ V, h#cd libpng-1.2.5( P/ o: l7 Y2 ]+ C% j) p
#cp scripts/makefile.std makefile \\不要用--prefix自定义安装目录,影响gd的安装 S; e6 I' r9 ~- S1 ?
#make( }4 u% h% {) L' W; [( c
#make install 安装jpeg; E$ i: p; |& k- S# a
#mkdir /usr/local/modules/jpeg60 P, G! L x0 B: Y5 R" p
#mkdir /usr/local/modules/jpeg6/bin
% P6 I$ ?2 {2 V1 K0 T" N#mkdir /usr/local/modules/jpeg6/lib& B0 k1 \, f, G7 O
#mkdir /usr/local/modules/jpeg6/include5 u* D5 z- X; N, T- P9 y6 k# s
#mkdir /usr/local/modules/jpeg6/man1 P+ ]% r! N% @& q0 Z& z
#mkdir /usr/local/modules/jpeg6/man/man1
, H) C, o% N9 Y9 X; \. _2 V#cd /data/software6 O4 U0 ~5 x, B/ o1 S5 b3 e, \) i; ~* @
#tar xzvf jpegsrc.v6b.tar.gz9 S% v* z$ K8 _
#./configure --prefix=/usr/local/modules/jpeg6 --enable-shared --enable-static; Z: ~7 z$ Y% M# ?6 T% P2 i0 e
#make5 {5 f% G& H8 {# y+ F+ J' c
#make install 安装gd
# c. G& \7 a$ x$ I6 P! ~#cd /data/software
1 P, ?. a: s' F8 Y, C+ Z: G#tar xzvf gd-2.0.33.tar.gz
9 n1 z1 ]- Z r5 m5 V#./configure --prefix=/usr/local/modules/gd --with- jpeg=/usr/local/modules/jpeg6 --with-png --with-zlib --with-freetype=/usr/local/modules/freetype- ]$ {2 r# c3 v0 E% {% P* G
#make
5 |$ x* Z5 j0 H8 E6 L#make install 最后,在安装nagios时#./configure步骤加一组参数:--with-gd-lib=/usr/local/modules/gd/lib 原始的Nagios中文版不能绘制中文字符串,与GD的字库处理方式有关。GD有自己的字库文件(点阵形式、ASC码编码)。gdImageString的第二个参数即GD自己的字库的索引,第五个参数则是一个ASC编码的字符串。而GD自己的字库是不支持中文的。显然,大名鼎鼎的GD不可能只支持自己的字库,他用函数gdImageStringFT来支持用外部字库绘制utf-8编码的字符串,这里面包含了中文的支持。 gdImageStringFT (gdImage * im, int *brect, int fg, char *fontlist,double ptsize, double angle, int x, int y, char *string),函数名中的“FT”就是freetype的意思,这个函数通过调用freetype包,支持解析.ttf格式(ttf是TrueType Font的缩写)的字库文件,只要找到Linux下的中文字库的位置,作为第四个参数传给该函数,并且保证char *string是utf-8编码,就能顺利绘制中文字符串。在我的调试环境下,修改如下:, G' B& K% d; A0 _
原函数:
% j, J3 m7 N0 [/ K% ?% o/ X* W+ QgdImageString(map_image,gdFontSmall,x-(string_width/2),y-(2*string_height),(unsigned char *)buffer,text_color);
+ ?# O' V! w: \+ q0 e+ S0 {修改后:3 k, Z! g! e8 ?$ k. T/ O3 v
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);
- s- W+ k4 {2 V6 J, A3 S0 V(gdImageString和gdImageStringFT详细的功能和参数说明见GD安装包下的说明文档index.html) 由于Nagios是从配置文件中读取设备名字符串然后绘制到屏幕上,所以如果配置文件本身是utf-8编码,如上修改后,重装Nagios就可以顺利显示了。如果配置文件不是utf-8,那么可以通过两种方法解决: 第一种:将配置文件转成utf-8编码。这样不用再度修改源码,但个人不赞成这种方法,理由是:由于Nagios的CGI是用C写的,而C是基于ASC编码的,Nagios又没有借助第三方数据库,而是依赖于读写自己创建的大量配置文件和日志文件,其中用到很多基于ASC编码的字符串处理函数,虽然都是英文的,而英文的ASC编码和utf-8完全相同,但是如果将Nagios的相关文件都转成utf-8编码,可能会导致一些潜在的问题。 第二种:在gdImageStringFT之前加一个字符串编码转换函数,将读入的非utf-8编码字符串buffer转换成utf-8编码,再传给gdImageStringFT处理。这样的字符串编码转换函数网上有很多资源,在此限于篇幅不详述。 |