MRTGでルーターやスイッチのトラフィック監視をしているんですが、WindowsサーバーのCPUなども見ておきたいな
と言う事でどうやって値をとろうかなと考えていたら、VB.netで書きだしてMRTGに読ませたらいいのでは?と
思って作ってみました。
サーバーのリソース監視程度なら、SNMPで出来るんだけどね。
あえてSNMPを使用せず、カスタムスクリプトでやってみました。
以前にルーター温度計とかも作ってたので大丈夫でしょう。
MRTGは所定のフォーマットに従ったデータであれば、別のプログラムが作ったデータからグラフを作ることができます。
例えばCPU温度と部屋の温度の関係とか、油温と油圧のグラフとかそう言うのもできます。
MRTGの文法は以下のとおり
30
50
34000
Sample Data
という4行のデータを渡せばOKです。
この場合だと、30が第一系列の値、50が第二系列の値、3400がシステムのアップタイム、Sample Dataがデータの説明です。
MRTGは必ず二つの系列を使用しますので、一列だけでいい場合は二列目は0でいいです。
例2
49 ←dat11
0 ←data2
34050 ←System Uptime
Sample Data ←Label
システムアップタイムも適当でいいです。
このフォーマットに合う形で、出力するスクリプトを作ります。
と言ってもVB.netなんでゴリゴリ書いたわけですが。
スクリプト編
こんなのVBScriptでできそうなんですが、VB.netが慣れてるのでそっちで作ります。
便利なことにWindowsXP以降だと、システムの各情報を一発で取れるメソッドが有りますので
そう言うのを使ってしまいます。
PerformanceCounterというのを使います。
これは管理ツールの中にあるパフォーマンスモニターで表示される内容と同じ物が取れます。
色んな物が取れますがここでは、ディスクの転送量とCPU使用率とメモリー使用率を取得します。
VB.netで宣言するとこんな感じ
Dim DiskLoadValue As New PerformanceCounter
で、サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
Module Module1 Dim CPULoad As New PerformanceCounter Dim MemoryLoad As New PerformanceCounter Dim DiskLoadTotal As New PerformanceCounter Dim SystemUpTime As New PerformanceCounter Private Function func_SystemUpTimeValue() 'システム起動時間の取得 Dim OutValue As Double 'パフォーマンスカウンターのインスタンス設定 SystemUpTime.CategoryName = "System" SystemUpTime.CounterName = "System Up Time" SystemUpTime.MachineName = "." '測定値の取得 OutValue = SystemUpTime.NextValue '四捨五入 If OutValue > 0 Then OutValue = System.Math.Floor((OutValue * 1) + 0.5) Else OutValue = 0 End If '戻り値を返す func_SystemUpTimeValue = OutValue.ToString End Function Private Function func_CPULoadValue() 'CPU使用率の取得 Dim OutString As String Dim OutValue As Single 'パフォーマンスカウンターのインスタンス設定 CPULoad.CategoryName = "Processor" CPULoad.CounterName = "% Processor Time" CPULoad.InstanceName = "_Total" CPULoad.MachineName = "." '測定値の取得 OutValue = CPULoad.NextValue '四捨五入 If OutValue > 0 Then OutValue = System.Math.Floor((OutValue * 1) + 0.5) Else OutValue = 0 End If 'MRTG書式に変換 OutString = OutValue.ToString & vbCrLf & "0" & vbCrLf & func_SystemUpTimeValue() & vbCrLf & "% Processor Time" '戻り値を返す func_CPULoadValue = OutString End Function Private Function func_MemoryLoadValue() 'メモリー使用率の取得 Dim OutString As String Dim OutValue As Single Dim dCoef As Double = System.Math.Pow(10, 1) 'パフォーマンスカウンターのインスタンス設定 MemoryLoad.CategoryName = "Memory" MemoryLoad.CounterName = "% Committed Bytes In Use" MemoryLoad.MachineName = "." '測定値の取得 OutValue = MemoryLoad.NextValue '四捨五入 If OutValue > 0 Then OutValue = System.Math.Floor((OutValue * 1) + 0.5) Else OutValue = 0 End If 'MRTG書式に変換 OutString = OutValue.ToString & vbCrLf & "0" & vbCrLf & func_SystemUpTimeValue() & vbCrLf & "% Committed Bytes In Use" func_MemoryLoadValue = OutString End Function Private Function func_DiskLoadValue() 'ハードディスク転送量の取得 Dim OutString As String Dim OutValue As Single 'パフォーマンスカウンターのインスタンス設定 DiskLoadTotal.CategoryName = "LogicalDisk" DiskLoadTotal.CounterName = "Disk Transfers/sec" DiskLoadTotal.InstanceName = "_Total" DiskLoadTotal.MachineName = "." '測定値の取得 OutValue = DiskLoadTotal.NextValue '四捨五入 If OutValue > 0 Then OutValue = System.Math.Floor((OutValue * 1) + 0.5) Else OutValue = 0 End If 'MRTG書式に変換 OutString = OutValue.ToString & vbCrLf & "0" & vbCrLf & func_SystemUpTimeValue() & vbCrLf & "Disk Total Transfers/sec" '戻り値を返す func_DiskLoadValue = OutString End Function Sub Main() Dim cmdArgs() As String Dim outString As String Dim RunCheck As Boolean = False Dim selectnumber As Integer Try cmdArgs = System.Environment.GetCommandLineArgs selectnumber = Convert.ToInt32(cmdArgs(1)) Catch ex As Exception Console.WriteLine("引数取得失敗") End Try Select Case selectnumber Case 0 'ディスク outString = func_DiskLoadValue() Threading.Thread.Sleep(1000) outString = func_DiskLoadValue() Console.WriteLine(outString.ToString) RunCheck = True Case 1 'CPU outString = func_CPULoadValue() Threading.Thread.Sleep(1000) outString = func_CPULoadValue() Console.WriteLine(outString.ToString) RunCheck = True Case 2 'メモリ outString = func_MemoryLoadValue() Threading.Thread.Sleep(1000) outString = func_MemoryLoadValue() Console.WriteLine(outString.ToString) RunCheck = True End Select If RunCheck = True Then Exit Sub Else '引数の指定がなかった場合 outString = func_DiskLoadValue() Threading.Thread.Sleep(1000) outString = func_DiskLoadValue() Console.WriteLine(outString.ToString) End If End Sub End Module |
コマンドラインアプリケーションとして、コンパイルして引数を指定して実行すると
MRTG用のフォーマットで出力されます。
LoadValue.exe 0
という感じで使用します。
LoadValue.exe 0
ディスク転送量
LoadValue.exe 1
CPU使用率
LoadValue.exe 2
メモリー使用率(コミットした量なので、実際に使用している割合だと思う)
この結果をリダイレクトしてやれば完成です。
例
LoadValue.exe 1 > \\192.168.101\logs\cpu.log
こんな感じでsamba経由で送り付けます。
MRTGサーバー側でcatすれば終わりです。
続きはまた次回へ