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

最近把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环境变量

  1. #!/bin/sh
  2. LOGDIR=/var/log
  3. date >> $LOGDIR/debug.log
  4. echo "---------------------------------" >> $LOGDIR/debug.log
  5. echo "$@" >> $LOGDIR/debug.log
  6. echo "---------------------------------" >> $LOGDIR/debug.log
  7. env >> $LOGDIR/debug.log
  8. echo "---------------------------------" >> $LOGDIR/debug.log
  9. locale >> $LOGDIR/debug.log
  10. /usr/bin/rrdtool.local "$@"
  11. echo "" >> $LOGDIR/debug.log
复制代码



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

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

  1. LANG=C
  2. LC_CTYPE="C"
  3. LC_NUMERIC="C"
  4. LC_TIME="C"
  5. LC_COLLATE="C"
  6. LC_MONETARY="C"
  7. LC_MESSAGES="C"
  8. LC_PAPER="C"
  9. LC_NAME="C"
  10. LC_ADDRESS="C"
  11. LC_TELEPHONE="C"
  12. LC_MEASUREMENT="C"
  13. LC_IDENTIFICATION="C"
  14. LC_ALL=
  15. LANG=
  16. LC_CTYPE="POSIX"
  17. LC_NUMERIC="POSIX"
  18. LC_TIME="POSIX"
  19. LC_COLLATE="POSIX"
  20. LC_MONETARY="POSIX"
  21. LC_MESSAGES="POSIX"
  22. LC_PAPER="POSIX"
  23. LC_NAME="POSIX"
  24. LC_ADDRESS="POSIX"
  25. LC_TELEPHONE="POSIX"
  26. LC_MEASUREMENT="POSIX"
  27. LC_IDENTIFICATION="POSIX"
  28. 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

  1. #!/bin/sh
  2. export LANG=zh_CN.gb18030
  3. /usr/bin/rrdtool.local "$@"

 

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

 

你可能感兴趣的:(xnix)