Windowsでサービス化されたtomcatのパフォーマンスデータを取得する(typeperf,jstatとか色々)

#はじめに

windowsってなんか苦手。なんでだろう。けど仕事だ。調べなきゃ。
2時間かけて試したことを二度と時間かけて調べたくないのでパフォーマンスデータの取得の仕方をまとめてみます。

windowsサービスであげたtomatに対してデータをとることを前提としています。
これが結構ハマりポイント。

# typeperf

## パフォーマンスカウンタ

取得する値をパフォーマンスカウンタで決めて、それをtypeperfの引数に渡すことで情報を取得できます。
パフォーマンスカウンタの一覧は下記にありますのでこちらを見てください。
http://technet.microsoft.com/ja-jp/library/cc748731.aspx
このへんとっておけば十分じゃなかろうか。ってことで下記を取得しました。

| 設定 | 設定値 |
|:-----------|:------------|
|"\Processor(_Total)\% Processor Time"|全体のCPU使用率(複数のCPUの平均値だから参考にならんかも）|
|"System\Processor Queue Length"|CPU待ち行列にあるスレッド数|
|"\Process(Tomcat7-8002)\% Processor Time"|プロセスのプロセッサ使用率|
|"\Memory\Available MBytes"|空メモリ（ＭＢ）
|"\Memory\Pages /sec"|メモリとディスクの間のデータのやり取りの回数。そりゃ少ないほうがいい。|
|"\Process(_Total)\Working Set"|全体の物理メモリ使用量|
|"\Process(Tomcat7-8002)\Working Set"|プロセスの物理メモリ使用量(たぶんbyte)|

Tomcat7-8002 となっている部分はサービス名となります。適宜修正してください。
サービス決め打ちで取れるんですねー。ってのを今回調べて初めて知りました。

## 実行方法

-si で取得間隔を決めて、パフォーマンスカウンタを並べてあげます。

``` コマンド
typeperf -si 3 "\Processor(_Total)\% Processor Time" "System\Processor Queue
Length" "\Process(Tomcat7-8002)\% Processor Time" "\Memory\Available MBytes"
"\Memory\Pages /sec" "\Process(_Total)\Working Set"
"\Process(Tomcat7-8002)\Working Set"
```

``` 取得結果
"12/05/2014　09:06:50.429","14.337685","0.000000","0.000000","888.000000","1931710464.000000","101322752.000000"
"12/05/2014　09:06:53.455","18.685048","1.000000","0.000000","884.000000","1940983808.000000","101322752.000000"
```

デフォルトではCSVで取得できますが、TSVなどにも変更できます。
オプションの詳細については下記を参照してください。
http://technet.microsoft.com/en-us/library/bb490960.aspx

# jconsole(windowsとか関係ないっす）

jconsoleはGUIで提供されるJavaのモニタリングツールです。heapの情報やクラスパスなどほんといろんな情報が見れます。

## 事前準備

tomcat起動時にcatalina.batでbin/setenv.batを読むように作られていますので、ここでclasspathの設定をしてあげます。
下記はwindowsの例となりますが、tomcatのインストーラーでインストールした場合は、とtomcat7w.exeを起動し、Javaタブ内で設定してあげます。
linuxの場合はsetenv.shとなります。

```setenv.bat
set CATALINA_OPTS=-server -Xms128m -Xmx256m -XX:+HeapDumpOnOutOfMemoryError
-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=7085
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
```

これでtomcatを起動すると7085Portが利用可能になりそこに対してjconsoleで接続することになります。

## jconsoleの実行

コマンドプロンプトで叩きます。
```
jconsole
```

JavaMonitoring&ManagementConsoleが上がってきますので、リモートプロセスにチェックをし、localhost:7085を入力し、接続ボタンを押せば見ることができます。
今回は認証の設定はしていませんが、tomcat起動時のjmxのオプションに認証を設定した場合はそのユーザ名、パスワードを入力してあげてください。

# jstat

jconsoleではGUIで様々な情報をみることができましたが集計のことを考えるとログに落としておきたいですよね。jstatの他にも色々コマンドがありますが今回はheapの状況を見たかったのでjstatを動かしてみます。

## プロセスが見つからない？

linuxであればjpsコマンドを叩いてvmid(プロセスID）を特定してそれをjconsoleに渡してあげることでモニタリングできます。

ちなみに・・・jpsでプロセスIDが見つからない場合はみているhsperfdata_XXXが間違っている可能性があります。linux版のtomcatでは$CATALINA_BASE/tempをみるのでそれをjpsの引数で指定することで取得可能です。こんな感じ。

```
jps -J-Djava.io.tmpdir=/usr/local/tomcat/temp
```

話がそれました・・・・windows上でサービス化されたtomcatのプロセスIDに対してjconsoleを打っても[not found]が返却されます。
これはなぜかというとサービス化されたプロセスはSystemユーザで起動されているため見えない。と言っています。（管理者ユーザでコマンドプロンプトを開いても同じ結果です）

## systemユーザで起動されたプロセスに対してjconsoleを叩きたい。

PsExec.exe経由でコマンドを実行するとsystemユーザにsudo(みたいなこと)して実行してくれます。

1.PsExec.exe.を取得してパスを通します。
インストールは不要で、ただ置くだけで利用できます。
http://technet.microsoft.com/ja-jp/sysinternals/bb897553.aspx
2.jstatを動かします。

```
PsExec.exe -s C:\tools\jdk1.6.0_31\bin\jstat.exe -gc プロセスID 間隔(ミリ秒）
```

# jstatでタイムスタンプを表示する。

めでたくjstatでデータ取れるようになりましたがtimestampが出てません。-tというオプションでVM起動からの経過時刻を表示できますのでそれを利用しようかと思いましたが起動時間って・・・と思ってやめました。

gawkを使ってやります。こんなかんじ。

```
PsExec.exe -s C:\tools\jdk1.6.0_31\bin\jstat.exe -gc -t 202212 1000 | gawk '{print strftime("\"%m/%d/%Y %H:%M:%S\""), $0; fflush()}'
```

そうするとこんなかんじで結果が取れます。

```
Starting C:\tools\jdk1.6.0_31\bin\jstat.exe on S1208C00306-T1...
"12/05/2014 11:31:37" Timestamp        S0C    S1C    S0U    S1U      EC       EU
OC         OU       PC     PU    YGC     YGCT    FGC    FGCT     GCT
"12/05/2014 11:31:37"        177612.2 21888.0 22208.0  64.0   0.0   42944.0 38992.2   174784.0   24367.0   21888.0 21764.1     10    2.918   0     0.000 2.918
"12/05/2014 11:31:38"        177613.2 21888.0 22208.0  64.0   0.0   42944.0 38992.2   174784.0   24367.0   21888.0 21764.1     10    2.918   0     0.000 2.918
"12/05/2014 11:31:39"        177614.2 21888.0 22208.0  64.0   0.0   42944.0 38992.2   174784.0   24367.0   21888.0 21764.1     10    2.918   0     0.000 2.918
```

ちょっとした悩みとしてはstrftimeではミリ秒までとれないっぽいんだよなぁ。。
http://www.gnu.org/software/gawk/manual/gawk.html#Time-Functions

# ということで

あとはリダイレクトしてファイルに落としてExcelに食わすなり、cygwinでtailで眺めたり好きにしてください。