さくらのVPSでOSgridのパフォーマンス監視設定
今回は、さくらのVPSおよびOSgridのパフォーマンスの視覚化について触れていきたいと思います。
内容
はじめに
さくらのVPS512MBを借りていて、OSgridに接続する自分が運用するOpesSimサーバ*1に複数アバターを作成して、テストで入ってみるとなんだか重いことが多かったので、実際のところどのような状況になっているのだろうかと思い、データを取得しグラフ化してみました。
パフォーマンスを監視することはサーバの管理にとって適切なリソースなのかを把握するのに重要です。そして、数値データだけではなかなか把握しにくいので、グラフにして視覚化し把握することも重要です。
さくらのVPSはOpenSimのテストのみの目的で借りているので、システム側のリソース監視とOpenSim側のリソース監視をすることによってほぼ、OpenSimのシステムとしてのパフォーマンスを知ることができます。
では、システムとOpenSimのリソース監視(統計情報)について見ていきたいと思います。
Stats(統計情報)
さくらのVPSのStats(統計情報)
ほぼOpensimの運用しか使用していないので、CPU、メモリ、ネットワークの状況についてはOpensimで使用するものとみなすことができるので、Opensimのstatsと一緒に統計情報を取得します。CentOSでは、sysstatを使用すれば、ログを取得できますし、さくらのVPSではデフォルトでインストールされています。
OpenSimのStats(統計情報)
OpenSimより出力される統計情報
以下に示すものがOpenSimより統計情報として出力されます。私なりの説明を加えるので、間違えていたら指摘していただきたいです。
値 | 説明 |
---|---|
AgentCount | SIMにいるユーザー(Avatar)の数 |
ChildAgentCount | SIMにはいないがこのSIMのオブジェクト?を表示しているユーザー(Avatar)の数 |
GCMemory | OpenSim.exeが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放した量 |
ObjectCount | SIMのオブジェクトの数 |
PhysicsFrame | 物理的エンジンが実行されているフレーム数 |
PhysicsUpdateFrame | 物理的エンジンで更新のあったフレーム数(たぶん) |
PWSMemory | OpenSim.exeの実行プロセスのメモリ使用量(ソースを見るとSystem.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64;で取得している) |
ThreadCount | OpenSim.exeのスレッド数 |
TotalFrame | 総フレーム数(たぶん)詳しくは、OpenSim/Region/Framework/Scenes/Scene.csを見たほうがいい |
EventFrame | イベントフレーム数(たぶん)詳しくは、OpenSim/Region/Framework/Scenes/Scene.csを見たほうがいい |
LandFrame | 土地のフレーム数(たぶん)詳しくは、OpenSim/Region/Framework/Scenes/Scene.csを見たほうがいい |
LastFrameTime | 完了フレーム数(たぶん)詳しくは、OpenSim/Region/Framework/Scenes/Scene.csを見たほうがいい |
TimeDilation | 実時間に対する物理的シミュレーションレート。 1.0 はフルスピードで地域が実行されていることを示し、0.5 はその半分のスピードで物理的作用が実行されていることを示す |
SimFPS | SIMのFPS |
PhysicsFPS | SIMの物理的エンジンが実行されているFPS |
AgentUpdatesPerSecond | SIMのユーザー(Avatar)が更新される率。 通常は 1 秒あたり 20 回の更新で、地域に多くのエージェントがいる場合、この値は低下するらしい |
ObjectUpdatesPerSecond | SIMのオブジェクトが更新される率。 通常は 1 秒あたり 20 回の更新で、地域に多くのエージェントがいる場合、この値は低下するらしい |
ActiveObjectCount | SIMにおける移動中または変更中のオブジェクトの数 |
ActiveScripts | ユーザー(Avatar)が装着しているスクリプトを含む、SIMで現在実行されているスクリプトの数 |
ScriptEventsPerSecond | SIMで 1 秒間に実行されている LSL オペレーション コードの数 |
InPacketsPerSecond | SIMで 受信されたUDP パケット |
OutPacketsPerSecond | SIMで 送信されたUDP パケット |
UnackedBytes | unacked(応答確認なしデータのバイト数) |
PendingDownloads | 保留中のSIMからのAssetダウンロード数。 これが 1 よりも大きい値の場合、これはノートカードやスクリプトの閲覧、オブジェクトの rez において遅延が生じる可能性があることを意味するらしい |
PendingUploads | 保留中のSIMへのAssetデータの現在のアップロード数です。 この数値がゼロ以外だと、テレポート実行の際、パフォーマンスに問題が起こる可能性があるらしい |
TotalFrameTime | SIMでフレームごとに実行している操作の完了までにかかる時間 |
NetFrameTime | ネットワーク データの受信に対してかかった時間 |
PhysicsFrameTime | 物理的作用のシミュレーション実行にフレームが費やした時間。 通常は 5 ミリ秒未満らしい |
SimulationFrameTime | その他のシミュレーション実行にフレームが費やした時間 (エージェントの動き、天候のシミュレーションなど) |
AgentFrameTime | エージェント(Avatar)へのオブジェクト データの更新および送信にかかった時間 |
ImagesFrameTime | イメージ データの更新およびエージェント(Avatar)への転送にかかった時間 |
Webでの統計情報の出力
OpenSimの統計情報は、ブラウザでも確認できるようです。
http://opensimulator.org/wiki/Web_Statistics_Moduleによると、OpenSim.ini において
[WebStats] enabled=true
とし(ない場合は追加します)、ブラウザで以下のようにURIを入力することで
http://サーバのIPアドレス:9000/SStats/
統計情報を見ることができます。ただし、認証をかけることができないようなので、誰からも見ることが出来る環境では、reloadを数多く短時間にすることなどで高負荷を発生しすることができるという可能性があるため、falseにしておいたほうが良いと思われます。(OSgridのデフォルトだとenabled=trueなのですが、何か意図があって使用しているのかもしれません?要調査です。)*2
XMLによる統計情報の出力
OpenSimの統計情報は、XMLの出力も可能なようです。JSONはないんだろうかという疑問は浮かびますが*3。
http://opensimulator.org/wiki/Monitoring_Moduleによると、OpenSim.ini においてデフォルトでXMLの出力は有効になっているので、使用したくない場合は、明示的にfalseにしてあげる必要があるようです。今回は、このXMLによる統計情報の出力を使ってデータを収集するので、falseにすることはありません。
XMLでの出力は以下のようにして確認することができます。
http://サーバのIPアドレス:9000/monitorstats/UUID
当方の環境はメガリージョンですが、monitorstatsの仕様は、複数SIMがありポートをそれぞれ割り当てていますが、1SIMのように認識するため、各SIMに割当たっているポートではなく9000のみを使用し、UUIDを変えればいいようです。
ブラウザを用いて確認すると以下のように出力されます。
<data> <AgentCountMonitor>0</AgentCountMonitor> <ChildAgentCountMonitor>0</ChildAgentCountMonitor> <GCMemoryMonitor>511221760</GCMemoryMonitor> <ObjectCountMonitor>12585</ObjectCountMonitor> <PhysicsFrameMonitor>0</PhysicsFrameMonitor> <PhysicsUpdateFrameMonitor>0</PhysicsUpdateFrameMonitor> <PWSMemoryMonitor>2796699648</PWSMemoryMonitor> <ThreadCountMonitor>0</ThreadCountMonitor> <TotalFrameMonitor>0</TotalFrameMonitor> <EventFrameMonitor>0</EventFrameMonitor> <LandFrameMonitor>0</LandFrameMonitor> <LastFrameTimeMonitor>63</LastFrameTimeMonitor> <TimeDilationMonitor>1</TimeDilationMonitor> <SimFPSMonitor>55.3333320617676</SimFPSMonitor> <PhysicsFPSMonitor>56.6666679382324</PhysicsFPSMonitor> <AgentUpdatesPerSecondMonitor>0</AgentUpdatesPerSecondMonitor> <ObjectUpdatesPerSecondMonitor>0</ObjectUpdatesPerSecondMonitor> <ActiveObjectCountMonitor>0</ActiveObjectCountMonitor> <ActiveScriptsMonitor>760</ActiveScriptsMonitor> <ScriptEventsPerSecondMonitor>0</ScriptEventsPerSecondMonitor> <InPacketsPerSecondMonitor>1</InPacketsPerSecondMonitor> <OutPacketsPerSecondMonitor>1.33333337306976</OutPacketsPerSecondMonitor> <UnackedBytesMonitor>0</UnackedBytesMonitor> <PendingDownloadsMonitor>0</PendingDownloadsMonitor> <PendingUploadsMonitor>0</PendingUploadsMonitor> <TotalFrameTimeMonitor>4</TotalFrameTimeMonitor> <NetFrameTimeMonitor>0</NetFrameTimeMonitor> <PhysicsFrameTimeMonitor>4</PhysicsFrameTimeMonitor> <SimulationFrameTimeMonitor>0</SimulationFrameTimeMonitor> <AgentFrameTimeMonitor>0</AgentFrameTimeMonitor> <ImagesFrameTimeMonitor>0</ImagesFrameTimeMonitor> </data>
このXMLを定期的に取得し、視覚化することで今回の目的が達成されます。
では、次に実際に視覚化する手順を見ていきます。
視覚的にしてみる
1時間毎、日毎、週ごとなど、取得したデータを視覚化し、トレンド把握し、分析することで、どの程度のパフォーマンスなのかを把握することができます。
視覚化の要件として、以下を設定しました。
- システム側およびOpensimから出力されるXMLの統計情報を一つのツールで蓄積できる
- 一つのツールでグラフ化することができる
- 制限付きの公開をする
調べるとcollectd*4というツールを使用すれば、1.が実現でき、1.でのデータをrrdtool*5というツールを使用することで、2.が実現できるようでした。そしてApacheを使えば、3.が実現できることがわかりました。
その他にも実現できるものを調べていたら、リッチなサーバサイドのアプリケーションによる実現もあったのですが、リッチなUIはいりませんし、ある程度データが確認出来ればいいし、サーバに余計な負荷を掛けたくないので、collectdで蓄積したrrdtool形式のデータをshellでrrdtoolを実行することでグラフ化しています。その方法を以下に示します。
システム側およびOpensimから出力されるXMLの統計情報の蓄積について(collectd)
collectdのインストール
[root@foo ~]# yum install collectd
collectdのインストールと同時にグラフ化するツールであるrrdtoolのインストールも同時にしておきます。
[root@foo ~]# yum install rrdtool
collectdからrrdtoolで描画できるデータを出力するためのプラグインをインストールします。
[root@foo ~]# yum install collectd-rrdtool
collectdの起動の確認
デフォルトのcollectdの設定では、CPUとメモリとネットワークインターフェイスについて取得しているので、確認のために起動し、rrd形式での出力がされているか確認します。
[root@foo ~]# /etc/init.d/collectd start
データが出力されているか確認します。collectdから出力されるデータはデフォルトでは/var/lib/collectd/にサーバのFQDNのディレクトリ以下に作成されるようです。
[root@foo ~]# ls -la /var/lib/collectd/サーバのFQDN/
CPUやmemoryのディレクトリができているか確認します。
タイムスタンプが起動した時刻であり、ディレクトリの中にファイルができていることを確認します。
[root@foo ~]# ls -la /var/lib/collectd/サーバのFQDN/memory/
collectdの設定
collectdでデータを取得するためには、以下2点を行う必要があります。
- こういう形式でデータを取るからねという定義を指定する
- どこからどういうデータを取得するという設定をする
http://opensimulator.org/wiki/Collectdにおいて、どのような定義をすればいいのか、どこからどういうデータを取得する設定をすることについて記述してあるので、参考にして進めていきます。
まず、CentOSの場合、取得するデータを保存する際のデフォルトの定義が
/usr/share/collectd/types.db
にあるので、OpenSimで出力されるデータを追加し、定義します。
[root@foo ~]# vi /usr/share/collectd/types.db
Dvgtu_agent_count value:GAUGE:0:U Dvgtu_child_agent_count value:GAUGE:0:U Dvgtu_gc_memory value:GAUGE:0:U Dvgtu_object_count value:GAUGE:0:U Dvgtu_physics_frame value:GAUGE:0:U Dvgtu_physics_update value:GAUGE:0:U Dvgtu_pws_memory value:GAUGE:0:U Dvgtu_thread_count value:GAUGE:0:U Dvgtu_total_frame value:GAUGE:0:U Dvgtu_event_frame value:GAUGE:0:U Dvgtu_land_frame value:GAUGE:0:U Dvgtu_last_frame value:GAUGE:0:U Dvgtu_time_dilatation value:GAUGE:0:U Dvgtu_sim_fps value:GAUGE:0:U Dvgtu_physics_fps value:GAUGE:0:U Dvgtu_agent_updates_per_sercond value:GAUGE:0:U Dvgtu_object_updates_per_second value:GAUGE:0:U Dvgtu_active_object_count value:GAUGE:0:U Dvgtu_active_scripts value:GAUGE:0:U Dvgtu_script_events_per_second value:GAUGE:0:U Dvgtu_in_paquets_per_second value:GAUGE:0:U Dvgtu_out_paquets_per_second value:GAUGE:0:U Dvgtu_unacked_bytes value:GAUGE:0:U Dvgtu_pending_downloads value:GAUGE:0:U Dvgtu_pending_uploads value:GAUGE:0:U Dvgtu_total_frame_time value:GAUGE:0:U Dvgtu_net_frame_time value:GAUGE:0:U Dvgtu_physics_frame_time value:GAUGE:0:U Dvgtu_simulation_frame_time value:GAUGE:0:U Dvgtu_agent_frame_time value:GAUGE:0:U Dvgtu_images_frame_time value:GAUGE:0:U
Dvgtu_agent_countなどは定義名ですので、任意につけることができます。ただし、以下に記述する/etc/collectd.conf内のLoadPlugin curl_xmlにおけるType "Dvgtu_agent_count"と合わせる必要があります。
そして、/etc/collectd.confにおいて、定義した名前にXMLで出力されるURIからどういう形式で取得したデータをローカルに保存するかを指定する必要があります。URIは以下のように記述します。
http://サーバのIPアドレス:9000/monitorstats/各SIMに割当たっているUUID
当方の環境はメガリージョンなので、ブラウザを用いて各SIMにおいてXMLが出力されるか、Regions.iniに記述してあるUUIDを各々入力して、確認します。
XMLが出力されることが確認できたら、/etc/collectd.confに設定を追加します。
[root@foo ~]# vi /etc/collectd.conf
LoadPlugin curl_xml <Plugin "curl_xml"> <URL "http://サーバのIPアドレス:9000/monitorstats/UUID"> Instance "Dvgtu0" <XPath "/data"> Type "Dvgtu_agent_count" ValuesFrom "AgentCountMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_child_agent_count" ValuesFrom "ChildAgentCountMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_gc_memory" ValuesFrom "GCMemoryMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_object_count" ValuesFrom "ObjectCountMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_physics_frame" ValuesFrom "PhysicsFrameMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_physics_update" ValuesFrom "PhysicsUpdateFrameMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_pws_memory" ValuesFrom "PWSMemoryMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_thread_count" ValuesFrom "ThreadCountMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_total_frame" ValuesFrom "TotalFrameMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_event_frame" ValuesFrom "EventFrameMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_land_frame" ValuesFrom "LandFrameMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_last_frame" ValuesFrom "LastFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_time_dilatation" ValuesFrom "TimeDilationMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_sim_fps" ValuesFrom "SimFPSMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_physics_fps" ValuesFrom "PhysicsFPSMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_agent_updates_per_sercond" ValuesFrom "AgentUpdatesPerSecondMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_object_updates_per_second" ValuesFrom "ObjectUpdatesPerSecondMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_active_object_count" ValuesFrom "ActiveObjectCountMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_active_scripts" ValuesFrom "ActiveScriptsMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_script_events_per_second" ValuesFrom "ScriptEventsPerSecondMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_in_paquets_per_second" ValuesFrom "InPacketsPerSecondMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_out_paquets_per_second" ValuesFrom "OutPacketsPerSecondMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_unacked_bytes" ValuesFrom "UnackedBytesMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_pending_downloads" ValuesFrom "PendingDownloadsMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_pending_uploads" ValuesFrom "PendingUploadsMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_total_frame_time" ValuesFrom "TotalFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_net_frame_time" ValuesFrom "NetFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_physics_frame_time" ValuesFrom "PhysicsFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_simulation_frame_time" ValuesFrom "SimulationFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_agent_frame_time" ValuesFrom "AgentFrameTimeMonitor/text()" </XPath> <XPath "/data"> Type "Dvgtu_images_frame_time" ValuesFrom "ImagesFrameTimeMonitor/text()" </XPath> </URL> 同様に、URLを変更、Instatnceを被らないようにして繰り返し </Plugin>
他にあと2点、/etc/collectd.confを修正します。
インターバルがデフォルトだと10秒ごとなので、20秒ごとにします。問い合わせの回数が多くなることでOpenSim.exeを高負荷にしてしまうのではないかということに対する考慮です。また、Swapのプラグインが有効になっていないので、コメントアウトを外して、有効にしてあげます。
[root@foo ~]# vi /etc/collectd.conf
Interval 20
LoadPlugin swap
collectdを再起動します。
[root@foo ~]# /etc/init.d/collectd restart
20秒ごとにデータを蓄積してくれるようになります。
ここで、システムとOpenSimの統計情報を取得するためのcollectdの設定が完了したので、初期起動の設定をしておきます。Run Level 3になっているかの確認です。
[root@foo ~]# chkconfig --list collectd [root@foo ~]# chkconfig collectd on [root@foo ~]# chkconfig --list collectd
統計情報のrrdtoolで描画について
では、collectdを使用することによって蓄積されたデータをグラフ化にするためのrrdtoolの簡単な使い方について触れていきたいと思います。詳しいrrdtoolの使用方法については、検索していただければと思います。
rrdtoolで描画する方法の例
memoryの使用率を描画する方法を一例としてあげます。
collectdのインストールと一緒にrrdtoolもインストールしておいたので、まずはrrdtoolがインストールされていることを確認します。
[takeshich@foo~]$ rrdtool
collectdから出力されるデータは
/var/lib/collectd/サーバのFQDN/
にInstanceごとにディレクトリ作成されその下にrrdファイルが作成されます。
PNGで320x100のグラフを現在より30分前からの30分間をプロットする例です
[takeshich@foo ~]$ RRDDATAFILE=/var/lib/collectd/サーバのFQDN/memory/ [takeshich@foo ~]$ rrdtool graph --imgformat PNG test.png \ --start -30minutes --width 320 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label "Memory_Used(Byte)" \ --title "Memory_Used" \ DEF:used_avg=${RRDDATAFILE}memory-used.rrd:value:AVERAGE \ DEF:used_min=${RRDDATAFILE}memory-used.rrd:value:MIN \ DEF:used_max=${RRDDATAFILE}memory-used.rrd:value:MAX \ CDEF:used_nnl=used_avg,UN,0,used_avg,IF \ AREA:used_nnl#bfbfff \ LINE1:used_nnl#0000ff:used \ GPRINT:used_avg:AVERAGE:"avg\:%4.2lf%s" \ GPRINT:used_min:MIN:"min\:%4.2lf%s" \ GPRINT:used_max:MAX:"max\:%4.2lf%s" \ GPRINT:used_avg:LAST:"cur\:%4.2lf%s\n"
OpenSimの出力データも同様にして描画できますので、GCMemoryの値を描画してみます。
以下パスに/etc/collectd.confで設定したプラグインと指定したinstance名でディレクトリが作られそこにデータが格納されるので、上記と同様に描画してみます。
/var/lib/collectd/サーバのFQDN/curl_xml-Dvgtu0
[takeshich@foo~]$ RRDDATAFILE=/var/lib/collectd/サーバのFQDN/curl_xml-Dvgtu0/ [takeshich@foo ~]$ rrdtool graph --imgformat PNG gc.png \ --start -30minutes --width 320 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label "ガベコレ(Byte)" \ --title "ガベコレ" \ DEF:used_avg=${RRDDATAFILE}Dvgtu_gc_memory.rrd:value:AVERAGE \ DEF:used_min=${RRDDATAFILE}Dvgtu_gc_memory.rrd:value:MIN \ DEF:used_max=${RRDDATAFILE}Dvgtu_gc_memory.rrd:value:MAX \ CDEF:used_nnl=used_avg,UN,0,used_avg,IF \ AREA:used_nnl#bfbfff \ LINE1:used_nnl#0000ff:used \ GPRINT:used_avg:AVERAGE:"avg\:%4.2lf%s" \ GPRINT:used_min:MIN:"min\:%4.2lf%s" \ GPRINT:used_max:MAX:"max\:%4.2lf%s" \ GPRINT:used_avg:LAST:"cur\:%4.2lf%s\n"
rrdtoolで描画(シェル)
上記のようにすれば描画できることが確認できたので、以下仕様でシェルを作成することにしました。
- 描画対象
- システム
- CPU使用率
- Memoryの使用量とSwapの量
- ネットワークインターフェイスのINとOUTの量
- OpenSim(取得できるデータすべて)
- システム
- 描画する期間
- 30分ごと
- 60分ごと
- 1日ごと
- 1週間ごと
- 描画タイミング
- 10分毎(期間が30分,60分)
- 1時間ごと(期間が1日,1週間)
- 描画サイズ(640x100)
OpenSimのデータは数が多いので、生成されたデータの一覧をそのまま描画する形になっています。メガリージョンの環境なので、積算してグラフ化したほうがいいものもあるようです。追って対応していきたいと考えています。
[root@foo ~]# vi /home/takeshich/rrdgraph.sh
#!/bin/bash #----------------------------------------------------------- #collectdで取得したデータをrrdtoolで描画するスクリプト #----------------------------------------------------------- # #・描画対象 # ・システム # ・CPU使用率 # ・Memoryの使用量とSwapの量 # ・ネットワークインターフェイスのINとOUTの量 # ・OpenSim(取得できるデータすべて) #・描画する期間 # ・30分ごと # ・60分ごと # ・1日ごと # ・1週間ごと #・描画タイミング(crontabで設定) # ・10分毎(期間が30分,60分) # ・1時間ごと(期間が1日,1週間) #・描画サイズ(640x100) #timezoneをいれないと曜日の表示がおかしいようなので TZ=Asia/Tokyo #collectdによりrrd形式のファイルが書き出されるPATH RRDDATAPATH=/var/lib/collectd/サーバのFQDN/ #出力される画像データを保存するディレクトリ OUTPUTDATAPATH=/home/opensimstats/ #画像ファイル名 PNGNAME="" #期間 TERM="" #----------------------------------------------------------- #OpenSimのデータを描画する #----------------------------------------------------------- opensim_plot() { #引数1:期間(0:HalfHourly1:Hourly,2:Daily,3:Weekly) #引数2:SIMの番号(メガリージョンなので、Regions.iniで設定している番号) case "$1" in "0" ) TERM=HalfHourly START="-31minutes" ;; "1" ) TERM=Hourly START="-61minutes" ;; "2" ) TERM=Daily START="-25hours" ;; "3" ) TERM=Weekly START="-8days" ;; "" ) exit ;; esac #OpenSimのデータが出力される場所 RRDDATAFILE=${RRDDATAPATH}curl_xml-Dvgtu$2/ #出力されるデータをリストにし、画像を作成 for LIST in `ls ${RRDDATAFILE}` do LISTNAME=`echo ${LIST} | sed -e "s/\.rrd//"` rrdtool graph --imgformat PNG ${OUTPUTDATAPATH}curl_xml-Dvgtu$2/${LISTNAME}_${TERM}.png \ --start ${START} --width 640 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label " " \ --title "$2:${LISTNAME}" \ DEF:opensim_avg=${RRDDATAFILE}${LIST}:value:AVERAGE \ DEF:opensim_min=${RRDDATAFILE}${LIST}:value:MIN \ DEF:opensim_max=${RRDDATAFILE}${LIST}:value:MAX \ AREA:opensim_avg#bfbfff \ LINE1:opensim_avg#0000ff:${LISTNAME} \ GPRINT:opensim_avg:AVERAGE:"avg\:%6.2lf%s" \ GPRINT:opensim_min:MIN:"min\:%6.2lf%s" \ GPRINT:opensim_max:MAX:"max\:%6.2lf%s" \ GPRINT:opensim_avg:LAST:"cur\:%6.2lf%s\n" done } #----------------------------------------------------------- #ネットワークインターフェイスのデータを描画する #----------------------------------------------------------- interface_plot() { #引数1:期間(0:HalfHourly1:Hourly,2:Daily,3:Weekly) case "$1" in "0" ) TERM=HalfHourly START="-31minutes" ;; "1" ) TERM=Hourly START="-61minutes" ;; "2" ) TERM=Daily START="-25hours" ;; "3" ) TERM=Weekly START="-8days" ;; "" ) exit ;; esac #画像ファイル名 PNGNAME="interface" #ネットワークインターフェイスのデータが出力される場所 RRDDATAFILE=${RRDDATAPATH}interface/ #画像を作成 rrdtool graph --imgformat PNG ${OUTPUTDATAPATH}${PNGNAME}_${TERM}.png \ --start ${START} --width 640 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label "Bytes" \ --title "eth0 network traffic_${TERM}" \ DEF:eth0_rx_avg=${RRDDATAFILE}if_packets-eth0.rrd:rx:AVERAGE \ DEF:eth0_rx_min=${RRDDATAFILE}if_packets-eth0.rrd:rx:MIN \ DEF:eth0_rx_max=${RRDDATAFILE}if_packets-eth0.rrd:rx:MAX \ DEF:eth0_tx_avg=${RRDDATAFILE}if_packets-eth0.rrd:tx:AVERAGE \ DEF:eth0_tx_min=${RRDDATAFILE}if_packets-eth0.rrd:tx:MIN \ DEF:eth0_tx_max=${RRDDATAFILE}if_packets-eth0.rrd:tx:MAX \ AREA:eth0_rx_avg#bfbfff \ LINE1:eth0_rx_avg#0000ff:rx\(IN\) \ GPRINT:eth0_rx_avg:AVERAGE:"avg\:%6.2lf%s" \ GPRINT:eth0_rx_min:MIN:"min\:%6.2lf%s" \ GPRINT:eth0_rx_max:MAX:"max\:%6.2lf%s" \ GPRINT:eth0_rx_avg:LAST:"cur\:%6.2lf%s\n" \ LINE1:eth0_tx_avg#00e000:tx\(OUT\) \ GPRINT:eth0_tx_avg:AVERAGE:"avg\:%6.2lf%s" \ GPRINT:eth0_tx_min:MIN:"min\:%6.2lf%s" \ GPRINT:eth0_tx_max:MAX:"max\:%6.2lf%s" \ GPRINT:eth0_tx_avg:LAST:"cur\:%6.2lf%s\n" } #----------------------------------------------------------- #メモリのデータを描画する #----------------------------------------------------------- memory_plot() { #引数1:期間(0:HalfHourly1:Hourly,2:Daily,3:Weekly) case "$1" in "0" ) TERM=HalfHourly START="-31minutes" ;; "1" ) TERM=Hourly START="-61minutes" ;; "2" ) TERM=Daily START="-25hours" ;; "3" ) TERM=Weekly START="-8days" ;; "" ) exit ;; esac #画像ファイル名 PNGNAME="Memory" #メモリのデータが出力される場所 RRDDATAFILE=${RRDDATAPATH}memory/ #Swapのデータが出力される場所 RRDDATAFILE_SWAP=${RRDDATAPATH}swap/ #画像を作成 rrdtool graph --imgformat PNG ${OUTPUTDATAPATH}${PNGNAME}_${TERM}.png \ --start ${START} --width 640 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label "Memory_Used(Byte)" \ --title "Memory_Used_${TERM}" \ DEF:used_avg=${RRDDATAFILE}memory-used.rrd:value:AVERAGE \ DEF:used_min=${RRDDATAFILE}memory-used.rrd:value:MIN \ DEF:used_max=${RRDDATAFILE}memory-used.rrd:value:MAX \ CDEF:used_nnl=used_avg,UN,0,used_avg,IF \ DEF:sused_avg=${RRDDATAFILE_SWAP}swap-used.rrd:value:AVERAGE \ DEF:sused_min=${RRDDATAFILE_SWAP}swap-used.rrd:value:MIN \ DEF:sused_max=${RRDDATAFILE_SWAP}swap-used.rrd:value:MAX \ CDEF:sused_nnl=sused_avg,UN,0,sused_avg,IF \ CDEF:used_stk=used_nnl,sused_nnl,+ \ AREA:used_stk#bff7bf \ LINE1:used_stk#00e000:swap \ GPRINT:sused_avg:AVERAGE:"avg\:%4.2lf%s" \ GPRINT:sused_min:MIN:"min\:%4.2lf%s" \ GPRINT:sused_max:MAX:"max\:%4.2lf%s" \ GPRINT:sused_avg:LAST:"cur\:%4.2lf%s\n" \ AREA:used_nnl#bfbfff \ LINE1:used_nnl#0000ff:used \ GPRINT:used_avg:AVERAGE:"avg\:%4.2lf%s" \ GPRINT:used_min:MIN:"min\:%4.2lf%s" \ GPRINT:used_max:MAX:"max\:%4.2lf%s" \ GPRINT:used_avg:LAST:"cur\:%4.2lf%s\n" } #----------------------------------------------------------- #CPUのデータを描画する #----------------------------------------------------------- cpu_plot() { #引数1:CPU番号 #引数2:期間(0:HalfHourly1:Hourly,2:Daily,3:Weekly) case "$2" in "0" ) TERM=HalfHourly START="-31minutes" ;; "1" ) TERM=Hourly START="-61minutes" ;; "2" ) TERM=Daily START="-25hours" ;; "3" ) TERM=Weekly START="-8days" ;; "" ) exit ;; esac #画像ファイル名 PNGNAME=CPU #CPUのデータが出力される場所 RRDDATAFILE=${RRDDATAPATH}cpu-$1/ #画像を作成 rrdtool graph --imgformat PNG ${OUTPUTDATAPATH}${PNGNAME}$1_${TERM}.png \ --start ${START} --width 640 --height 100 \ -n DEFAULT:0:"Bitstream Vera Sans" \ --vertical-label "%" \ --rigid --upper-limit 100 \ --title ${PNGNAME}$1${TERM} \ DEF:idle_min=${RRDDATAFILE}cpu-idle.rrd:value:MIN \ DEF:idle_avg=${RRDDATAFILE}cpu-idle.rrd:value:AVERAGE \ DEF:idle_max=${RRDDATAFILE}cpu-idle.rrd:value:MAX \ CDEF:idle_nnl=idle_avg,UN,0,idle_avg,IF \ DEF:wait_min=${RRDDATAFILE}cpu-wait.rrd:value:MIN \ DEF:wait_avg=${RRDDATAFILE}cpu-wait.rrd:value:AVERAGE \ DEF:wait_max=${RRDDATAFILE}cpu-wait.rrd:value:MAX \ CDEF:wait_nnl=wait_avg,UN,0,wait_avg,IF \ DEF:nice_min=${RRDDATAFILE}cpu-nice.rrd:value:MIN \ DEF:nice_avg=${RRDDATAFILE}cpu-nice.rrd:value:AVERAGE \ DEF:nice_max=${RRDDATAFILE}cpu-nice.rrd:value:MAX \ CDEF:nice_nnl=nice_avg,UN,0,nice_avg,IF \ DEF:user_min=${RRDDATAFILE}cpu-user.rrd:value:MIN \ DEF:user_avg=${RRDDATAFILE}cpu-user.rrd:value:AVERAGE \ DEF:user_max=${RRDDATAFILE}cpu-user.rrd:value:MAX \ CDEF:user_nnl=user_avg,UN,0,user_avg,IF \ DEF:system_min=${RRDDATAFILE}cpu-system.rrd:value:MIN \ DEF:system_avg=${RRDDATAFILE}cpu-system.rrd:value:AVERAGE \ DEF:system_max=${RRDDATAFILE}cpu-system.rrd:value:MAX \ CDEF:system_nnl=system_avg,UN,0,system_avg,IF \ DEF:softirq_min=${RRDDATAFILE}cpu-softirq.rrd:value:MIN \ DEF:softirq_avg=${RRDDATAFILE}cpu-softirq.rrd:value:AVERAGE \ DEF:softirq_max=${RRDDATAFILE}cpu-softirq.rrd:value:MAX \ CDEF:softirq_nnl=softirq_avg,UN,0,softirq_avg,IF \ DEF:interrupt_min=${RRDDATAFILE}cpu-interrupt.rrd:value:MIN \ DEF:interrupt_avg=${RRDDATAFILE}cpu-interrupt.rrd:value:AVERAGE \ DEF:interrupt_max=${RRDDATAFILE}cpu-interrupt.rrd:value:MAX \ CDEF:interrupt_nnl=interrupt_avg,UN,0,interrupt_avg,IF \ DEF:steal_min=${RRDDATAFILE}cpu-steal.rrd:value:MIN \ DEF:steal_avg=${RRDDATAFILE}cpu-steal.rrd:value:AVERAGE \ DEF:steal_max=${RRDDATAFILE}cpu-steal.rrd:value:MAX \ CDEF:steal_nnl=steal_avg,UN,0,steal_avg,IF \ CDEF:steal_stk=steal_nnl \ CDEF:interrupt_stk=interrupt_nnl,steal_stk,+ \ CDEF:softirq_stk=softirq_nnl,interrupt_stk,+ \ CDEF:system_stk=system_nnl,softirq_stk,+ \ CDEF:user_stk=user_nnl,system_stk,+ \ CDEF:nice_stk=nice_nnl,user_stk,+ \ CDEF:wait_stk=wait_nnl,nice_stk,+ \ CDEF:idle_stk=idle_nnl,wait_stk,+ \ AREA:idle_stk#ffffff \ LINE1:idle_stk#ffffff:idle \ GPRINT:idle_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:idle_min:MIN:"min\:%3.2lf%s" \ GPRINT:idle_max:MAX:"max\:%3.2lf%s" \ GPRINT:idle_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:wait_stk#ffebbf \ LINE1:wait_stk#ffb000:wait \ GPRINT:wait_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:wait_min:MIN:"min\:%3.2lf%s" \ GPRINT:wait_max:MAX:"max\:%3.2lf%s" \ GPRINT:wait_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:nice_stk#bff7bf \ LINE1:nice_stk#00e000:nice \ GPRINT:nice_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:nice_min:MIN:"min\:%3.2lf%s" \ GPRINT:nice_max:MAX:"max\:%3.2lf%s" \ GPRINT:nice_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:user_stk#bfbfff \ LINE1:user_stk#0000ff:user \ GPRINT:user_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:user_min:MIN:"min\:%3.2lf%s" \ GPRINT:user_max:MAX:"max\:%3.2lf%s" \ GPRINT:user_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:system_stk#ffbfbf \ LINE1:system_stk#ff0000:system \ GPRINT:system_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:system_min:MIN:"min\:%3.2lf%s" \ GPRINT:system_max:MAX:"max\:%3.2lf%s" \ GPRINT:system_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:softirq_stk#ffbfff \ LINE1:softirq_stk#ff00ff:softirq \ GPRINT:softirq_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:softirq_min:MIN:"min\:%3.2lf%s" \ GPRINT:softirq_max:MAX:"max\:%3.2lf%s" \ GPRINT:softirq_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:interrupt_stk#e7bfe7 \ LINE1:interrupt_stk#a000a0:interrupt \ GPRINT:interrupt_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:interrupt_min:MIN:"min\:%3.2lf%s" \ GPRINT:interrupt_max:MAX:"max\:%3.2lf%s" \ GPRINT:interrupt_avg:LAST:"cur\:%3.2lf%s\n" \ AREA:steal_stk#bfbfbf \ LINE1:steal_stk#000000:steal \ GPRINT:steal_avg:AVERAGE:"avg\:%3.2lf%s" \ GPRINT:steal_min:MIN:"min\:%3.2lf%s" \ GPRINT:steal_max:MAX:"max\:%3.2lf%s" \ GPRINT:steal_avg:LAST:"cur\:%3.2lf%s\n" } #実行 cpu_plot 0 0 > /dev/null cpu_plot 0 1 > /dev/null cpu_plot 1 0 > /dev/null cpu_plot 1 1 > /dev/null cpu_plot 2 0 > /dev/null cpu_plot 2 1 > /dev/null memory_plot 0 > /dev/null memory_plot 1 > /dev/null interface_plot 0 > /dev/null interface_plot 1 > /dev/null opensim_plot 0 0 > /dev/null opensim_plot 0 1 > /dev/null opensim_plot 0 2 > /dev/null opensim_plot 0 3 > /dev/null opensim_plot 1 0 > /dev/null opensim_plot 1 1 > /dev/null opensim_plot 1 2 > /dev/null opensim_plot 1 3 > /dev/null
1時間と1週間ものは、1時間ごとに実行するので、スクリプトを分けます。
[root@foo ~]# vi /home/takeshich/rrdgraph_w.sh
#!/bin/bash #1時間おきに日毎と週毎のを作成 #timezoneをいれないと曜日の表示がおかしいようなので TZ=Asia/Tokyo . /home/takeshich/rrdgraph.sh cpu_plot 0 2 > /dev/null cpu_plot 0 3 > /dev/null cpu_plot 1 2 > /dev/null cpu_plot 1 3 > /dev/null cpu_plot 2 2 > /dev/null cpu_plot 2 3 > /dev/null memory_plot 2 > /dev/null memory_plot 3 > /dev/null interface_plot 2 > /dev/null interface_plot 3 > /dev/null opensim_plot 2 0 > /dev/null opensim_plot 2 1 > /dev/null opensim_plot 2 2 > /dev/null opensim_plot 2 3 > /dev/null opensim_plot 3 0 > /dev/null opensim_plot 3 1 > /dev/null opensim_plot 3 2 > /dev/null opensim_plot 3 3 > /dev/null
作成した2つのスクリプトを定期実行させるためにcrontabを編集します。1時間おきのものは毎時4分に実行することとします。rrdgraph.shが10分おきに実行されているので被らないようにするためです。
[root@foo ~]# crontab -e
*/10 * * * * /home/takeshich/rrdgraph.sh 04 0-23/1 * * * /home/takeshich/rrdgraph_w.sh