LoginSignup
2
0

WebSphere LibertyのMP MetricsデータをCSVで出力するシェル・プログラム

Last updated at Posted at 2024-03-12

WebSphere LibertyのMicroProfile Metricsを使用すると、RESTコールで、簡単にLibertyのパフォーマンス・データを取得することができます。ただ、パフォーマンスの応答が、Prometheus Text形式であり、Prometheusなどのツールと連携する場合には、問題ありませんが、Prometheusが無い環境では、グラフ化をしたい場合に、手間がかかると思います。
LibertyのMP Metricsの応答データを、CSV出力するシェル・プログラムを紹介します。CSVに変換することで、エクセルなどを用いて、必要なパフォーマンス・データを容易にグラフ化できます。

MP Metricsを取得するためのLibertyの設定

MP Metricsを有効化し、RESTコールで、Metrics(パフォーマンス)データを取得できるようにするためには、Libertyのserver.xmlに下記の定義を追加します。

server.xml
<server>
    <featureManager>
        <feature>mpMetrics-5.0</feature>
    </featureManager>
    <mpMetrics authentication="false"/>
</server>

<mpMetrics authentication="false"/>を追加することで、認証なしで、Metricsデータを取得することができます。認証ありでの設定についてはOpen Libertyのドキュメントを参照ください。
Open Libertyドキュメント - MicroProfile Metrics
上記の設定を行ったLibertyサーバーに対して、/metricsのURLにGETリクエストを送信すると、下記のようにPrometheus Text形式の応答が返ります。

$ curl http://localhost:9080/metrics
# HELP servlet_responseTime_total_seconds The total response time of this servlet since the start of the server.
# TYPE servlet_responseTime_total_seconds gauge
servlet_responseTime_total_seconds{mp_scope="vendor",servlet="io_openliberty_microprofile_metrics_5_0_public_internal_PublicMetricsRESTProxyServlet",} 0.06364990000000001
# HELP classloader_loadedClasses_total Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
# TYPE classloader_loadedClasses_total counter
classloader_loadedClasses_total{mp_scope="base",} 10576.0

// 途中略

# HELP gc_total Displays the total number of collections that have occurred. This attribute lists -1 if the collection count is undefined for this collector.
# TYPE gc_total counter
gc_total{mp_scope="base",name="global",} 0.0
gc_total{mp_scope="base",name="scavenge",} 73.0
# HELP requestTiming_slowRequestCount The number of servlet requests that are currently running but are slow.
# TYPE requestTiming_slowRequestCount gauge
requestTiming_slowRequestCount{mp_scope="vendor",} 0.0
# HELP session_liveSessions The number of users that are currently logged in.
# TYPE session_liveSessions gauge
session_liveSessions{appname="default_host_metrics",mp_scope="vendor",} 1.0
$

#で始まる行は、Metrics項目の説明と、Metrics値の種類で、補足です。実際のMetricsの項目名と値は、#のない行です。

MP MetricsのデータをCSVに変換するシェル・プログラム

下記に、/metricsのURLを定期的に呼び、取得したMetricデータをCSV形式でファイルに記録するサンプル・シェル・プログラム(metrics2csv.sh)を紹介します。
実行方法は、下記のように、第一引数にmetricの取得間隔(秒)を指定し、標準出力をリダイレクトすることで、ファイルにCSV形式でMetricsデータを記録できます。計測を停止するには、[Ctrl]+[c]で停止してください。

$ ./metrics2csv.sh 30 > ./csv/metrics_myhostname_202403051935.csv

出力結果は、下記のようになります。

$ cat ./csv/metrics_myhostname_202403051935.csv
Shell start date = Tue Mar 5 19:35:03 JST 2024
Shell running host = myhost
Connect host = xxx.xxx.xxx.xxx
MPMetrics retrieve interval = 30 sec
--------------------
Metrics item num = 31
--------------------
date, time, classloader_loadedClasses_count{mp_scope="base";}, classloader_loadedClasses_total{mp_scope="base";}, classloader_unloadedClasses_total{mp_scope="base";}, cpu_availableProcessors{mp_scope="base";}, cpu_processCpuLoad_percent{mp_scope="base";}, cpu_processCpuTime_seconds{mp_scope="base";}, cpu_systemLoadAverage{mp_scope="base";}, gc_time_seconds_total{mp_scope="base";name="global";}, gc_time_seconds_total{mp_scope="base";name="scavenge";}, gc_total{mp_scope="base";name="global";}, gc_total{mp_scope="base";name="scavenge";}, jvm_uptime_seconds{mp_scope="base";}, memory_committedHeap_bytes{mp_scope="base";}, memory_maxHeap_bytes{mp_scope="base";}, memory_usedHeap_bytes{mp_scope="base";}, requestTiming_activeRequestCount{mp_scope="vendor";}, requestTiming_hungRequestCount{mp_scope="vendor";}, requestTiming_requestCount_total{mp_scope="vendor";}, requestTiming_slowRequestCount{mp_scope="vendor";}, servlet_request_total{mp_scope="vendor";servlet="io_openliberty_microprofile_metrics_5_0_public_internal_PublicMetricsRESTProxyServlet";}, servlet_responseTime_total_seconds{mp_scope="vendor";servlet="io_openliberty_microprofile_metrics_5_0_public_internal_PublicMetricsRESTProxyServlet";}, session_activeSessions{appname="default_host_metrics";mp_scope="vendor";}, session_create_total{appname="default_host_metrics";mp_scope="vendor";}, session_invalidated_total{appname="default_host_metrics";mp_scope="vendor";}, session_invalidatedbyTimeout_total{appname="default_host_metrics";mp_scope="vendor";}, session_liveSessions{appname="default_host_metrics";mp_scope="vendor";}, thread_count{mp_scope="base";}, thread_daemon_count{mp_scope="base";}, thread_max_count{mp_scope="base";}, threadpool_activeThreads{mp_scope="vendor";pool="LargeThreadPool";}, threadpool_size{mp_scope="vendor";pool="LargeThreadPool";}
2024/03/05, 19:35:03, 10578.0, 10578.0, 0.0, 16.0, 5.078023396707402E-5, 20.671875, -1.0, 0.0, 0.258, 0.0, 80.0, 10409.406, 1.37756672E8, 5.36870912E8, 5.638344E7, 1.0, 0.0, 7.0, 0.0, 6.0, 0.0883503, 0.0, 1.0, 1.0, 1.0, 0.0, 257.0, 254.0, 305.0, 3.0, 200.0
2024/03/05, 19:35:33, 10578.0, 10578.0, 0.0, 16.0, 3.250790757920611E-5, 20.6875, -1.0, 0.0, 0.258, 0.0, 80.0, 10439.448, 1.37756672E8, 5.36870912E8, 5.700348E7, 1.0, 0.0, 8.0, 0.0, 7.0, 0.0923153, 0.0, 1.0, 1.0, 1.0, 0.0, 257.0, 254.0, 305.0, 3.0, 200.0
2024/03/05, 19:36:03, 10578.0, 10578.0, 0.0, 16.0, 0.0, 20.6875, -1.0, 0.0, 0.258, 0.0, 80.0, 10469.475, 1.37756672E8, 5.36870912E8, 5.8364896E7, 1.0, 0.0, 9.0, 0.0, 8.0, 0.095949, 0.0, 1.0, 1.0, 1.0, 0.0, 257.0, 254.0, 305.0, 3.0, 200.0
2024/03/05, 19:36:33, 10578.0, 10578.0, 0.0, 16.0, 6.50493913929816E-5, 20.71875, -1.0, 0.0, 0.258, 0.0, 80.0, 10499.501, 1.37756672E8, 5.36870912E8, 6.053168E7, 1.0, 0.0, 10.0, 0.0, 9.0, 0.0994072, 0.0, 1.0, 1.0, 1.0, 0.0, 257.0, 254.0, 305.0, 3.0, 200.0
$

metrics2csvの内容を下記に添付しますので、自由に変更して活用ください。

metrics2csv.sh
#!/bin/bash

# 実行方法:
#   ./metrics2csv.sh ([metric取得間隔(秒)]) (> [結果出力ファイル名])
# 実行例: 
#   ./metrics2csv.sh 30 > metrics_hostname_hhmmss.csv
# 終了方法: 
#   [Ctrl]+[c]
# 実行例(バックグラウンド):
#   nohup ./metrics2csv.sh 30 > metrics_hostname_hhmmss.csv &
# 終了方法(バックグラウンド):
#   ps -ef | grep metrics2csv
#   kill <psコマンドで確認したプロセスID>

# 第一引数をメトリック取得の間隔に設定。引数が無い場合は60秒間隔とする。
if [ "$#" -eq 0 ]; then
  interval=60
elif [ "$#" -eq 1 ] && [[ "${1}" =~ ^[0-9]+$ ]]; then
  interval=${1}
else
  echo "エラー: 引数は、metric取得間隔の1個、または、0個(取得間隔は60秒)を指定します." >&2
  echo "実行方法: ./metrics2csv.sh ([metric取得間隔(秒)]) (> [結果出力ファイル名])"  >&2
  echo "実行例: ./metrics2csv.sh 30 > metrics_hostname_hhmmss.csv"  >&2
  exit 1
fi

echo "Shell start date = "$(date)
echo "Shell running host = "$(hostname)

# localhost
connecthost=localhost
# remote server
# connecthost=xxx.xxx.xxx.xxx

echo "Connect host = ""$connecthost"
echo "MPMetrics retrieve interval = ""$interval"" sec"

# Metric項目数
lastitemnum=0

# ここからループ
while true; do

  # dateコマンドで、日付と時刻部分を取得
  yyyymmdd=$(date '+%Y/%m/%d')
  hhmmss=$(date '+%H:%M:%S')

  # MPMetricの取得
  raw_metrics=$(curl -s http://"$connecthost":9080/metrics)

  # 必要な行のみ抽出 #で始まる項目の説明行を削除して、ソート
  row=$(echo "$raw_metrics" | egrep -v "^#" | sort)

  # MPMetricの項目数
  itemnum=$(echo "$row" | wc -l)

  # 「} 」で区切って、項目名と値を分離する
  # ヘッダー行は、最初の1回目のリクエストと、もし項目数が変わった時だけ、出力する
  if [ $((itemnum)) -ne $((lastitemnum)) ]; then

    echo "--------------------"
    echo "Metrics item num = ""$itemnum"
    echo "--------------------"

    lastitemnum="$itemnum"

    # 「}」で区切った前半が項目名。項目名の中の「,」は「;」に置き換え。CSVファイルとして開きやすくするため。
    item=$(echo "$row" | sed "s/,/;/g" | awk '{print ", " substr($0,1,index($0,"}") )}')

    # 項目の一、二列目は日付と時間とし、その後、項目名を出力
    echo "date, time""$item" | sed -z "s/\n//g"
    echo
    
  fi

  # 「}」で区切った後半が値
  value=$(echo "$row" |  awk '{print ", " substr($0,index($0,"}")+2 )}')

  # 一、二列目はcurl呼び出しの日付と時間を挿入し、その後、項目値を出力
  echo "$yyyymmdd"", ""$hhmmss""$value" | sed -z "s/\n//g"
  echo

  # コマンド引数で指定した秒数sleepして無限ループ
  sleep $interval

done

上記で掲載したサンプルの出力結果は、ほとんどLibertyをインストールしただけで、まだ、アプリケーションがデプロイされていない状態のLibertyの出力例なので、Metricsの項目数が、31と少ないですが、実際にアプリケーションがデプロイされると簡単に数百の項目数になります。
実際にMetricsデータを取得し、出力するデータを抽出しているのは、下記の部分になります。

metrics2csv-part.sh
  # MPMetricの取得
  raw_metrics=$(curl -s http://"$connecthost":9080/metrics)

  # 必要な行のみ抽出 #で始まる項目の説明行を削除して、ソート
  row=$(echo "$raw_metrics" | egrep -v "^#" | sort)

出力項目を、特定の項目にしぼる場合、例えば、HTTPセッションとスレッド・プールのデータ項目のみを出力する場合には、下記のように抽出条件を修正します。

metrics2csv-part2.sh
row=$(echo "$raw_metrics" | egrep -v "^#" | egrep "session|threadpool" | sort)

MP Metricsで取得できるデータ項目については、下記のドキュメントを参照ください。
Open Libertyドキュメント - MicroProfile Metrics 5.0 metrics reference
どのメトリックを見るべきかは、下記のQiitaの記事も参考になります。
Qiita - Libertyの性能情報をPythonのSidecarで取得する(mpMetrics)

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0