Linux/sarをグラフ化その2(gnuplotでグラフを描く

gnuplotの導入と、sarのグラフ作成例(2017-03-14)


sar の情報をグラフ化します。
同じ時間に別のリソースで何が起きているかを見るなら
やっぱり数値で見るより時系列のグラフにして並べると楽です。


なお、gnuplotのサンプル、使い方は gnuplot.info で見られます。

gnuplot のインストール

gnuplotはグラフ作成に便利なフリーウェアです。
早速ですが、インストールしていきます。

(とりあえず、情報を見ます)
# yum info gnuplot
(インストールされて無かったので、インストールしました)
# yum install gnuplot

そう、yum install して思い出したんですが、依存するパッケージが多いんです。

Install  1 Package (+24 Dependent packages)

(まだ GUI関連のパッケージが殆ど入っていないから、だろうか?)
今回はWebに繋がる環境なので、依存するものを自動で入れてもらえてホッとしています・・・

で、うちのCentOS 7環境に、
gnuplot 「4.6.2」 が入ったのですが、・・・何かがおかしい。

何かというと、「set format x '%H'」が正しく出ない。
%S(秒指定)で「%H(時間)」が出る??
同じデータを別環境(Lubuntu)のgnuplot 5.0.3 でグラフ化すると、正しく出る・・・

・・・*1
結局、gnuplot.info のダウンロードから(sourceforge.net/projects/gnuplot/files/gnuplot から)
最新版を入れる事にしました。

とりあえず、さきほど入れた奴は消しました
# yum remove gnuplot

結局、ソースコードから最新版をビルドします。
が、その前に2つほどパッケージを入れました。


私の環境だと、gd-devel が足りませんでした。
これは gnuplot を入れた後のエラーメッセージですが、

gnuplot> set terminal png
                     ^
        line 0: unknown or ambiguous terminal type; type just 'set terminal' for a list

WARNING: Plotting with an 'unknown' terminal.
No output will be generated. Please select a terminal with 'set terminal'.

これについては、
ソースから ./configure した時の、このメッセージが答えでした。

  libgd-based png, jpeg, and gif terminals: no (see config.log)

libgd が無い or バージョンが古い場合に出るようです。
pngを使うために gd を追加します。

# yum install gd-devel

今度は ./configure 実行時のメッセージで、
以下のように png が使えるようになっているはずです。

 libgd-based png, jpeg, and gif terminals: yes (with animated gif)

gdを入れるときにも依存パッケージはあるので、
やはりWebに繋がらない環境の場合はご注意を。


あと、私の環境では font が何も入っていませんでした。
フォント無しでも gnuplot は動くとは思いますが、
グラフ内で使える文字の制限やら、実行する時のWarningやらが嫌なので、
今回は liberation-font を入れる事にしました。

# fc-list
(そもそも fc-list が無い場合は、fontconfig未導入かも
 その場合は「yum info fontconfig」など参照。)

fc-list の実行結果が空っぽだったので、入れました。
特にどのフォントでなければならないというのは無いと思います。

# yum install liberation-serif-fonts
# fc-list
(今度は何か入っていることを確認)

ようやく話がもどって、今度こそ gnuplot のインストールです。
前述のようにダウンロードしたファイルを確認して、展開して、ビルドします。

# sha1sum  gnuplot-5.0.5.tar.gz
(sourceforge の「i」アイコンから、sha1が見れるので、同じことを確認)
# cd gnuplot-5.0.5
# ./configure
# make
# make check
# make install

make check は何か沢山表示されて何が起こっているのか分かりませんでした。
(うちの環境はGUIが無いのでX11関連はとうぜん全abortなのだけど、結局checkはOK?NG?どっち?
 make失敗した場合には、ちゃんとcheckが中断される仕様なのだろうか?)
ただ、チェック結果が詳細に表示されるので、失敗時の原因を探すときに便利かもしれません。

さておき、これで gnuplotを新しいものに差し替えました。
以下、実行できる&バージョンが上がっていることも確認できました。

# gnuplot -V
gnuplot 5.0 patchlevel 5

フォントのWarningについて(Could not find/open font when opening font "arial")

タイトルの通り、実行時に出るメッセージについてです。

Could not find/open font when opening font "arial", using internal non-scalable font

デフォルトの arialフォント を使おうとしたけどダメでした、と言っていますが、
これは

export GNUPLOT_DEFAULT_GDFONT=/usr/share/fonts/自分が持っているフォント.ttf

みたいに使用するフォントを環境変数指定すればOKです。
あるいは gnuplot時に

set term png font "使用するフォント"

など、
フォントを省略せず正しく指定するか。


余談ですが、
この件について少しコードを追ってみたのですが(term/gd.trm)
環境変数 GNUPLOT_DEFAULT_GDFONT が無ければ arial にハードコーディングされています。*2
エラーを見て、arial の代わりがあれば良いのか!?と勘違いして
  フォントの設定 ~/.config/fontconfig/fonts.conf を作って*3
   <alias> で arial を LiberationSerif で宣言したりしたけど
全く関係ありませんでした・・・
さておき・・・今回は自分用の環境だし、ソースも手元にあるので、直接書き換えます!

(gnuplot-5.0.5 にて)
term/gd.trm で「"arial"」の部分(一カ所)を「"使いたいフォントのフルPATH"」にしてから
make、 make install する。
フォントの一覧は「fc-list」コマンド等で確認できます。

これで環境変数無しで好きなフォントを使えます。

sarのグラフを描くshellの例

ようやく、グラフが描けます。
そしてグラフ書くのも一苦労でした・・・gnuplot の書式やルールに慣れておらず。
でも、これでサンプルができたし今後はもう大丈夫、・・・な筈です!

以下、グラフの作成例です。
SAR_INPUT に sar -o で取得したファイルを、
SAR_OUTPUT に出力先の png ファイルを指定します。

#!/bin/sh

SAR_INPUT=/var/log/sa/sa10
SAR_OUTPUT=./sar_image.png
SAR_INFO="cpu usage"

export LANG=C    # sar の時刻表示が日本語にならないようにする

# sar で欲しい情報を出力。今回は cpu なので -u オプションを使う。
# grep で取得する行
# egrep -vi で除外する行を指定する
# awk で一行目は項目名にする(BEGIN)、0.2fで小数点第2位まで出力。
sar -f $SAR_INPUT -u |\
  grep all |\
  egrep -vi '^$|average|Linux|CPU' |\
  awk '
    BEGIN{
      printf("%s,%s,%s,%s\n", "date", "total", "user", "sys");
    }
    {
      printf("%s,%0.2f,%0.2f,%0.2f\n", $1, 100-$8, $3, $5);
    }
  ' |\
  tee $0.tmp 

# ファイル $0.tmp からグラフを描く。
# ヒアドキュメント(EOS~EOS)でコマンドを渡す。
gnuplot <<EOS
  set terminal png
  set datafile separator "," # 入力データの区切り指定。デフォルトはスペース
  #set key outside left;     # 凡例の位置
  set output "$SAR_OUTPUT"   # 出力先
  set title  "$SAR_INFO"     # グラフタイトル
  set xdata time             # X軸が日時の場合は、それを伝える
  set timefmt "%H:%M:%S"     # 入力データの日時書式
  set format x '%H:%M'       # 出力グラフの日時書式
  #set xrange [*:*]          # 範囲指定 *:* は自動。
  #set xrange ["00:00:00":"18:00:00"] # 時刻は "" で囲んで、入力書式に合わせる
  #set xtics  3600
  #set yrange [0:100]
  plot  "$0.tmp" using 'date':'sys' with line, \
        "$0.tmp" using 'date':'user' with line, \
        "$0.tmp" using 'date':'total' with line
        # plot や replot などでグラフを描く
        # using には X軸:Y軸 を指定する
        #   入力の何列目か、あるいは入力一行目の項目名などで指定できる
        # ファイル名 "-" で標準入力を指定できるが、
        #   複数描くならば二本目以降エラーになるので注意
        #   (warning: Skipping data file with no valid points)
EOS

また、もし複数日にまたいでグラフ化する場合は、
sarの時刻書式(HH:MM:SS)では日付がないので、正しく処理されません。
(時系列に並び替えてグラフ化されて、日付がごっちゃになる)
そのため、gnuplot に渡す前にダミーの日付を書き足す必要があります。
(01/23:59:59、02/00:00:01 のように01/, 02/を付与してから、
 それらを timefmt "%d/%H:%M:%S" で受け取る、など)

余談。Excelじゃだめなの?

グラフ化する方法って、一長一短ですよね。

  • gnuplot
    早くて便利。ただし別途インストールが必要な場合が多い。
    (客先環境や職場、間借りしている環境で導入できない)
    あと、初心者は大抵の場合、泣く。*4
  • CSV形式にしてから、Excel
    結果報告が必要なら、データの整理分析ができるExcelは便利。
    ただしデータが大量になると、Excelが固まる。
    あと、手作業の魔力に魅入られる*5
  • CANVASタグ(HTML5)
    まだ使ったことが無いです。

CANVASタグ・・・あれ、HTMLで画像・・・TABLE?・・・TABLE!?
という訳で、次回が一番書きたかった内容です。

gnuplot無しでグラフを描く」へ
うそ、ちゃんとしたやつも作りました。


*1 ChangeLog見ましたが、そういう記述は無いし。でも最新版でビルドしたら直ったので、特に気にせずもう最新版にします。
*2 arial は、環境変数 GDFONTPATH からarial を探すらしいです(関数gdImageStringFTより)。つまりどのみち環境変数の設定が必要。
*3 fontconfig バージョンが2.10以前ならば ~/.font.conf らしいです。バージョンは yum info fontconfig 等で確認できます。システム全体の設定は /etc/fonts/fonts.conf です。
*4 泣きました。
*5 一回きりで終わらないなら、CVS取り込みからグラフ描画までVBA等で自動化するべき。しかし手でやると大いに仕事した気分になれるので、大抵は担当者が超速繊細な職人芸でグラフを手作りする。