MRTGのUTF-8対応

最終更新日時:2010-12-10 17:28:10
MRTG

概要


MRTG の出力は、日本語であれば EUC-JP で使用するのがしきたりのようで、UTF-8 では出力できません。
また、LANG=UTF-8 の環境で mrtg を実行すると以下のようなエラーが出力されることから、UTF-8 による出力は全くサポートされていないことが分かります。

 -----------------------------------------------------------------------
 ERROR: Mrtg will most likely not work properly when the environment
        variable LANG is set to UTF-8. Please run mrtg in an environment
        where this is not the case. Try the following command to start:
 
        env LANG=C /usr/local/mrtg-2/bin/mrtg xxx.cfg
 -----------------------------------------------------------------------


もはや過去の遺物と言って良い EUC-JP を使うのはあまり好ましくないので、MRTG を手っ取り早く UTF-8 に対応させる方法をここでは紹介します。

設定ファイルの変更


mrtg の設定ファイル中の Language の値を変更します。
なお、ここで変更を行うことにより、mrtg は正常に動作しなくなりますので、必要であれば cron 等の実行を停止してください。

 Language: utf8


出力ページ設定の変更


lib/mrtg2/locales_mrtg.pm ファイルに utf-8 の設定を記述します。
このファイル中には様々な言語の設定が記述されているので、この中に utf-8 の設定を追加するのが最良(いずれはそうなるはず)ですが、私は面倒なので以下のように utf-8 のみ記述したファイルを別途作成しました。

package locales_mrtg;

require 5.002; no locale; use strict;
%lang2tran::LOCALE= ( 'utf8' => \&utf8 );
sub utf8 { my $string = shift; return "" unless defined $string; my(%translations,%month,%wday);
my($i,$j); my(@dollar,@quux,@foo);
%translations = ( '^iso-8859-1' => 'utf-8', '^Maximal 5 Minute Incoming Traffic' => '最大5分受信量', '^Maximal 5 Minute Outgoing Traffic' => '最大5分送信量', '^the device' => 'デバイス', '^The statistics were last updated (.*)' => '更新日時 $1', '^Average\)' => '平均)', '^Average$' => '平均', '^Max$' => '最大', '^Current' => '最新', '^`Daily\' Graph \((.*) Minute' => '日グラフ($1分間', '^`Weekly\' Graph \(30 Minute' => '週グラフ(30分間', '^`Monthly\' Graph \(2 Hour' => '月グラフ(2時間', '^`Yearly\' Graph \(1 Day' => '年グラフ(1日', '^Incoming Traffic in (\S+) per Second' => '毎秒の受信$1数', '^Incoming Traffic in (\S+) per Minute' => '毎分の受信$1数', '^Incoming Traffic in (\S+) per Hour' => '毎時の受信$1数', '^Outgoing Traffic in (\S+) per Second' => '毎秒の送信$1数', '^Outgoing Traffic in (\S+) per Minute' => '毎分の送信$1数', '^Outgoing Traffic in (\S+) per Hour' => '毎時の送信$1数', '^at which time (.*) had been up for (.*)' => '$1の稼働時間 $2', '^Average max 5 min values for `Daily\' Graph \((.*) Minute interval\):' => '日グラフでの最大5分値の平均($1分間隔):', '^Average max 5 min values for `Weekly\' Graph \(30 Minute interval\):' => '週グラフでの最大5分値の平均(30分間隔):', '^Average max 5 min values for `Monthly\' Graph \(2 Hour interval\):' => '月グラフでの最大5分値の平均(2時間間隔):', '^Average max 5 min values for `Yearly\' Graph \(1 Day interval\):' => '年グラフでの最大5分値の平均(1日間隔):', #'^([kMG]?)([bB])/s' => '$1$2/秒', #'^([kMG]?)([bB])/min' => '$1$2/分', #'^([kMG]?)([bB])/h' => '$1$2/時', '^Bits$' => 'ビット', '^Bytes$' => 'バイト', '^In$' => '受信', '^Out$' => '送信', '^Percentage' => '比率', '^Ported to OpenVMS Alpha by' => 'OpenVMS Alphaへの移植', '^Ported to WindowsNT by' => 'WindowsNTへの移植', #'^and' => 'and', '^GREEN' => '緑', '^BLUE' => '青', '^DARK GREEN' => '深緑', '^MAGENTA' => 'マゼンタ', '^AMBER' => '琥珀' );
foreach $i (keys %translations) { my $trans = $translations{$i}; $trans =~ s/\|/\\|/; return $string if eval " \$string =~ s|\${i}|${trans}| "; };
%wday = ( 'Sunday' => '(日)', 'Monday' => '(月)', 'Tuesday' => '(火)', 'Wednesday' => '(水)', 'Thursday' => '(木)', 'Friday' => '(金)', 'Saturday' => '(土)', );
%month = ( 'January' => '1月', 'February' => '2月', 'March' => '3月', 'April' => '4月', 'May' => '5月', 'June' => '6月', 'July' => '7月', 'August' => '8月', 'September' => '9月', 'October' => '10月', 'November' => '11月', 'December' => '12月', );
@foo=($string=~/(\S+),\s+(\S+)\s+(\S+)\s+(.*)/); if($foo[0] && $wday{$foo[0]} && $foo[2] && $month{$foo[2]} ) { if($foo[3]=~/at/) { @quux=split(/\s+at\s+/,$foo[3]); } else { @quux=split(/ /,$foo[3],2); }; return "$quux[0]年$month{$foo[2]}$foo[1]日$wday{$foo[0]} $quux[1]"; };
return $string; };


mrtgコマンドの変更


上記2つの変更で基本的には UTF-8 での出力に対応できます。
ただし、LANG=UTF-8 の環境では mrtg の制御により実行できません。
以下のようにすると実行可能ですが、、、

 % env LANG=C /usr/local/mrtg-2/bin/mrtg xxx.cfg


少々気持ち悪いので、/usr/local/mrtg-2/bin/mrtg の以下の部分を削除することにより、いちいち LANG 設定を行わなくても実行できるようにします。

 65,78d64
 <     if ( $ENV{LANG} and $ENV{LANG} =~ /UTF.*8/i ){        
 <         my $args = join " ", map { /\s/ ? "\"$_\"" : $_ } @ARGV;
 <         $args ||= "";
 <         print <<ERR;
 < -----------------------------------------------------------------------
 < ERROR: Mrtg will most likely not work properly when the environment
 <        variable LANG is set to UTF-8. Please run mrtg in an environment
 <        where this is not the case. Try the following command to start:
 < 
 <        env LANG=C ${0} $args 
 < -----------------------------------------------------------------------
 < ERR
 <         exit 0;
 <     }


お問い合わせは 掲示板 にて。