最近在对Cacti进行二次开发,但是发现中文上面有点问题,花了大半天时间才搞定,所以觉得有必要总结一下。


环境说明: RHEL 6 + Cacti 0.8.8a + rrdtool 1.3


接下来会写好几个步骤,但是问题根源其实就只有一个:未统一编码。建议没有特殊要求的话,统一使用UTF-8编码。


1. 操作系统层面

1) 得安装中文支持,否则怎么都搞不了。


2) 确认当前的语言编码,echo $LANG看下吧。一般我们在/etc/sysconfig/i18n这个文件中修改。


2. 应用层面

1) Apache配置文件里默认会加上"AddDefaultCharset UTF-8",如果你没有用UTF-8编码,那么这就会导致问题;


2) MySQL服务器默认编码是latin1,这是没办法正确存储中文的,所以我们一般把它改成utf8.

[mysql]
default-character-set=utf8
[mysqld]
default-character-set=utf8
character-set-server=utf8

Cacti自带的sql文件没有指定编码,所以导入数据库之后是什么编码取决于你myql客户端程序采用什么编码。

如果之前没注意到这个问题,可以用mysqldump导出之后,把latin1改成utf8再导入即可。


3) 如果上面的配置都搞定之后,rrdtool就不会是问题了。

当然还有一种不常见的情况,那就是假如那就是你的系统默认编码必须使用GB18030,但是你想要UTF-8,倒是可以用网上流传的一种方法:

mv /usr/bin/rrdtool /usr/bin/rrdtool.local
touch /usr/bin/rrdtool
#!/bin/bash
export LANG=zh_CN.UTF-8
/usr/bin/rrdtool.local "$@"
chmod +x /usr/bin/rrdtool


3. Cacti自身的问题

1) Cacti未使用utf8编码来操作MySQL数据库

修改lib/database.php,增加一行:$cnn_id->Execute("set names 'utf8'");

while ($i <= $retries) {
    $cnn_id = ADONewConnection($dsn);
    $cnn_id->Execute("set names 'utf8'");
    if ($cnn_id) {
            return($cnn_id);
    }
    $i++;
    usleep(40000);
}


2) rrdtool没有正确获取中文

在lib/rrd.php中有一行:

"--title=" . cacti_escapeshellarg($graph["title_cache"]) . RRD_NL .

cacti_escapeshellarg函数在unix下直接调用PHP的escapeshellarg函数,但是该函数默认的LC_CTYPE是C,这种情况下非ASCII字符就会被破坏。

所以我们要显式声明下LC_CTYPE这个环境变量:

在文件lib/functions.php的最前面,添加一句代码:
setlocale(LC_CTYPE, "zh_CN.UTF-8");


3) 关于中文字体

其实上面讲过,只要系统有了中文支持,就会有中文字体。但是默认的字体不好看,我们可以优化下。

"RRDTool Default Font"这个选项我设置的是"文泉驿正黑 Bold",用的是pango命名语法,系统支持哪些字体可以用"fc-list"命令来查看,新增字体后用"fc-cache -fv"命令来刷新。


4) Cacti默认使用UTF-8编码,在新版的里面,HTML头里面也默认声明了。