您的位置:首页 > 编程语言

彻底弄清楚rrdtool乱码根本原因,可以不用修改rrdtool源代码显示中文了

2010-12-21 10:17 417 查看
最近把cacti从apache搬到了nginx+php-fpm的环境,程序打包部署的,什么都没有变,但是起来后发现图上的中文都是乱码,类似于:

 



 

 

开始搜索,也参考了无数文章,大多说的都是中文字体的设置问题。照着试了,没效果。后来尝试修改rrdtool,重新编译,又发现和freetype2的版本不协调。于是进入cacti的代码去看它是如何使用rrdtool来绘图的,保存命令行直接执行,也是可以正常显示中文的。于是又怀疑是运行nginx和php-fpm的用户locale问题,用运行用户跑命令行也是ok的。于是再用php页面去跑,果然是乱码了又。

 

其实这个问题就是locale问题,rrdtool源代码已经很清楚了,但是由于不了解nginx和php-fpm对环境变量的加载规则,还是摸不到头绪。终于还是发现了这篇文章,作者的思考过程可以借鉴,也同时告诉我们如何来跟踪这种locale问题导致的语言问题。特此抓贴分享下:

 

 

最近一直在折腾把cactiEZ搬到生产平台上已有的rhel4上,没有想到遇到了图表中文乱码的问题。

用的是系统自带的rrdtool,想起网上说要修改源代码才能正常显示,于是下了源代码进行编译。

下载1.2.27修改setlocale,编译~~~~重启httpd。结果打开IE一看,还是乱码。

是不是老版本的问题,下个最新的1.4.3试试。经过漫长的编译过程(有很多依赖库也要编译,郁闷),重新配置,重启httpd,还是乱码。是不是也要修改setlocale?打开rrd_graph.c ,我日,里面大变样,根本找不到原来的函数了。此路不通。

找来找去,乱码出现的原因百思不得其解。

试着直接命令行运行rrdtool,发现生成出来的图像中文是正常的。难道中文出在调用rrdtool上面?

于是写一个脚本检测传递给rrdtool环境变量

#!/bin/sh

LOGDIR=/var/log

date >> $LOGDIR/debug.log

echo "---------------------------------" >> $LOGDIR/debug.log

echo "$@" >> $LOGDIR/debug.log

echo "---------------------------------" >> $LOGDIR/debug.log

env >> $LOGDIR/debug.log

echo "---------------------------------" >> $LOGDIR/debug.log

locale >> $LOGDIR/debug.log

/usr/bin/rrdtool.local "$@"

echo "" >> $LOGDIR/debug.log

复制代码

将系统自带的rrdtool改名成 rrdtool.local,然后这个脚本保存成rrdtool

在cacti一看图,果然出现了猫腻。

LANG=C

LC_CTYPE="C"

LC_NUMERIC="C"

LC_TIME="C"

LC_COLLATE="C"

LC_MONETARY="C"

LC_MESSAGES="C"

LC_PAPER="C"

LC_NAME="C"

LC_ADDRESS="C"

LC_TELEPHONE="C"

LC_MEASUREMENT="C"

LC_IDENTIFICATION="C"

LC_ALL=

LANG=

LC_CTYPE="POSIX"

LC_NUMERIC="POSIX"

LC_TIME="POSIX"

LC_COLLATE="POSIX"

LC_MONETARY="POSIX"

LC_MESSAGES="POSIX"

LC_PAPER="POSIX"

LC_NAME="POSIX"

LC_ADDRESS="POSIX"

LC_TELEPHONE="POSIX"

LC_MEASUREMENT="POSIX"

LC_IDENTIFICATION="POSIX"

LC_ALL=

复制代码

调用rrdtool的时候locale都不对,肯定乱码。于是在脚本的前面添加了export LANG=zh_CN.gb18030。再运行一下,郁闷,还是乱码。

这样完全没有办法了。又翻来复去折腾了几遍,还是老样子。莫非大侠命绝于此。

怀着最后一丝希望点了一遍图表,突然原来图表时间轴上的星期现在能正常显示中文了,而备注和图表标题还是乱码,这一些好像都是从命令行传入的,而星期那一些不是传入的,是rrdtool自动生成的。

会不会是传给rrdtool的参数里中文乱码了?

于是马上修改脚本打印 echo "$@" >> /var/log/debug.log

果然,在debug.log里参数都是乱码的,这就说明传给rrdtool的时候中文都已经乱码了,rrdtool也就死活显示不出中文了。

由于cactiEZ 而且使用的gb2312编码,于是将/etc/sysconfig/i18n 里修改成gb18030 ,service httpd restart

重新进入cacti,看图,中文终于出来了!!!眼泪哗哗的。

最终总结:

1.rrdtool的中文显示与上下文locale有关。需要注意php调用rrdtool时的locale
2.cacti调用rrdtool时会丢失原有的locale,所以需要写一个脚本包装一下rrdtool,重新指定locale
3.cacti能否传递正常的参数给rrdtool,有赖于系统的locale,如果系统的默认locale与cacti应用的编码不对,可能不能正确的传递中文。

2、3点可能和apache以及php的机制有关,没有进一步的去研究。

我是基于cactiEZ修改的中文版进行的测试,原版可能修改的方法不一样,但原理肯定相通。另外,我试用的rrdtool是1.2.23、1.2.27和1.4.3。更老的版本是否可行未知,但可以按上面的思路排查问题。

附上:最终的脚本

将原来的/usr/bin/rrdtool 更名为 /usr/bin/rrdtool

将下面的代码保存为/usr/bin/rrdtool

#!/bin/sh

export LANG=zh_CN.gb18030

/usr/bin/rrdtool.local "$@"

 

转自:http://www.51cacti.cn/thread-250-1-1.html

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  脚本 nginx apache php c service
相关文章推荐