Libertyの性能情報をREST APIで取得するPythonのスクリプトを作成し、サイドカーコンテナとして動かしてみたメモ。
なお、Libertyの性能情報をREST APIで取得するには、JMXのRest Connectorを使う方法とMicroProfile Metricを使う方法があり、今回試しているのは前者。
mpMetricを使う方法は以下。
参考リンク
ローカルLibertyの準備
はじめにローカルでLibertyを動かして確認する。以下のようなserver.xml
でLibertyを起動する。
monitor-1.0
フィーチャーを追加することでWebSphere:type=JvmStats
やWebSphere:type=ThreadPoolStats
などのパフォーマンスデータが追加で取得できるようになる。ローカルJMX接続にはlocalConnector-1.0
が必要であり、REST APIでの接続にはrestConnector-2.0
が必要。また、RESTでは認証のための管理者ロールを持つユーザーが必要。
<server description="new server">
<!-- Enable features -->
<featureManager>
<feature>webProfile-8.0</feature>
<feature>monitor-1.0</feature>
<feature>localConnector-1.0</feature>
<feature>restConnector-2.0</feature>
</featureManager>
<!-- To access this server from a remote client add a host attribute to the following element, e.g. host="*" -->
<httpEndpoint id="defaultHttpEndpoint"
host="*"
httpPort="9080"
httpsPort="9443" />
<keyStore id="defaultKeyStore" password="password"/>
<basicRegistry>
<user name="jmxadmin" password="password" />
</basicRegistry>
<administrator-role>
<user>jmxadmin</user>
</administrator-role>
<!-- Automatically expand WAR files and EAR files -->
<applicationManager autoExpand="true"/>
<applicationMonitor updateTrigger="mbean"/>
<webApplication id="sample" location="sample.war" name="sample"/>
</server>
jconsole
Libertyの性能情報としてどのような情報がとれるのかをjconsoleで確認してみる。
ローカルJMX接続
jconsoleを起動する。
jconsole
「ローカル・プロセス」でws-server.jar defaultServer
を選択する。
あるいは、${server.output.dir}/logs/state/com.ibm.ws.jmx.local.address
の内容を「リモート・プロセス」に入力する。こちらの方がより高い信頼性があるとKnowledgeCenterには書いてある。どちらの場合も、セキュアな接続は失敗するので非セキュアで接続する。
MBeansタブでどのような情報が取得できるのか確認できる。
REST接続
jconsoleからREST接続するのは少々ややこしい。
jconsoleにいろいろオプションをつけて起動する必要がある。
jconsole \
-J-Djava.class.path=${JAVA_HOME}/lib/jconsole.jar:${JAVA_HOME}/lib/tools.jar:${WLP_HOME}/clients/restConnector.jar \
-J-Djavax.net.ssl.trustStore=${WLP_HOME}/usr/servers/defaultServer/resources/security/key.jks \
-J-Djavax.net.ssl.trustStorePassword=password \
-J-Djavax.net.ssl.trustStoreType=jks
${server.output.dir}/logs/state/com.ibm.ws.jmx.rest.address
の内容を「リモート・プロセス」に入力する。このときの接続先のホスト名は証明書のCNと一致する必要があるので、192.168.99.1
とかになっていたらlocalhost
にする必要があるかもしれない。ブラウザで証明書を確認してそれに合わせること。
curl
curl
コマンドでREST APIから情報がとれるのかを確認する。https://localhost:9443/IBMJMXConnectorREST/mbeans/
でどのようなMBeanがあるのか確認できる。以下ではWebSphere
を含むもののみを抽出。ここで返されているURLにアクセスすることで性能情報を取得できる。
$ curl -s -k --basic -u jmxadmin:password https://localhost:9443/IBMJMXConnectorREST/mbeans/ | jq '.[] | select( .objectName | test("WebSphere") )'
{
"objectName": "WebSphere:type=ServletStats,name=com.ibm.ws.jmx.connector.server.rest.JMXRESTProxyServlet",
"className": "com.ibm.ws.webcontainer.monitor.ServletStats",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.ws.jmx.connector.server.rest.JMXRESTProxyServlet%2Ctype%3DServletStats"
}
{
"objectName": "WebSphere:name=com.ibm.websphere.config.mbeans.FeatureListMBean",
"className": "com.ibm.ws.config.featuregen.internal.FeatureListMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.websphere.config.mbeans.FeatureListMBean"
}
{
"objectName": "WebSphere:name=com.ibm.websphere.runtime.update.RuntimeUpdateNotificationMBean",
"className": "com.ibm.ws.runtime.update.internal.RuntimeUpdateNotificationMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.websphere.runtime.update.RuntimeUpdateNotificationMBean"
}
{
"objectName": "WebSphere:name=com.ibm.ws.jmx.mbeans.sessionManagerMBean",
"className": "com.ibm.ws.session.SessionManagerMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.ws.jmx.mbeans.sessionManagerMBean"
}
{
"objectName": "WebSphere:name=com.ibm.ws.config.serverSchemaGenerator",
"className": "com.ibm.ws.config.schemagen.internal.ServerSchemaGeneratorImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.ws.config.serverSchemaGenerator"
}
{
"objectName": "WebSphere:feature=kernel,name=ServerInfo",
"className": "com.ibm.ws.kernel.server.internal.ServerInfoMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3Dkernel%2Cname%3DServerInfo"
}
{
"objectName": "WebSphere:type=ThreadPoolStats,name=Default Executor",
"className": "com.ibm.ws.monitors.helper.ThreadPoolStats",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3DDefault+Executor%2Ctype%3DThreadPoolStats"
}
{
"objectName": "WebSphere:name=com.ibm.ws.jmx.mbeans.generatePluginConfig",
"className": "com.ibm.ws.webcontainer.osgi.mbeans.GeneratePluginConfigMBean",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.ws.jmx.mbeans.generatePluginConfig"
}
{
"objectName": "WebSphere:feature=PluginUtility,name=PluginConfigRequester",
"className": "com.ibm.ws.webserver.plugin.runtime.requester.PluginConfigRequesterImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3DPluginUtility%2Cname%3DPluginConfigRequester"
}
{
"objectName": "WebSphere:feature=CacheAdmin,type=DynaCache,name=DistributedMap",
"className": "com.ibm.ws.cache.MBeans",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3DCacheAdmin%2Cname%3DDistributedMap%2Ctype%3DDynaCache"
}
{
"objectName": "WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint",
"className": "com.ibm.ws.channelfw.internal.chains.EndPointInfoImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3Dchannelfw%2Cname%3DdefaultHttpEndpoint%2Ctype%3Dendpoint"
}
{
"objectName": "WebSphere:type=SessionStats,name=default_host/IBMJMXConnectorREST",
"className": "com.ibm.ws.session.monitor.SessionStats",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Ddefault_host%2FIBMJMXConnectorREST%2Ctype%3DSessionStats"
}
{
"objectName": "WebSphere:name=com.ibm.websphere.config.mbeans.ServerXMLConfigurationMBean",
"className": "com.ibm.ws.config.xml.internal.ServerXMLConfigurationMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dcom.ibm.websphere.config.mbeans.ServerXMLConfigurationMBean"
}
{
"objectName": "WebSphere:type=JvmStats",
"className": "com.ibm.ws.monitors.helper.JvmStats",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Atype%3DJvmStats"
}
{
"objectName": "WebSphere:feature=kernel,name=ServerEndpointControl",
"className": "com.ibm.ws.kernel.server.internal.ServerEndpointControlMBeanImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3Dkernel%2Cname%3DServerEndpointControl"
}
{
"objectName": "WebSphere:service=com.ibm.ws.kernel.filemonitor.FileNotificationMBean",
"className": "com.ibm.ws.kernel.filemonitor.internal.FileNotificationImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aservice%3Dcom.ibm.ws.kernel.filemonitor.FileNotificationMBean"
}
{
"objectName": "WebSphere:feature=restConnector,type=FileService,name=FileService",
"className": "com.ibm.ws.filetransfer.internal.mbean.FileService",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3DrestConnector%2Cname%3DFileService%2Ctype%3DFileService"
}
{
"objectName": "WebSphere:service=com.ibm.websphere.application.ApplicationMBean,name=sample",
"className": "com.ibm.ws.app.manager.internal.ApplicationConfigurator$NamedApplication$2",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Dsample%2Cservice%3Dcom.ibm.websphere.application.ApplicationMBean"
}
{
"objectName": "WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint-ssl",
"className": "com.ibm.ws.channelfw.internal.chains.EndPointInfoImpl",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3Dchannelfw%2Cname%3DdefaultHttpEndpoint-ssl%2Ctype%3Dendpoint"
}
{
"objectName": "WebSphere:feature=restConnector,type=FileTransfer,name=FileTransfer",
"className": "com.ibm.ws.filetransfer.internal.mbean.FileTransfer",
"URL": "/IBMJMXConnectorREST/mbeans/WebSphere%3Afeature%3DrestConnector%2Cname%3DFileTransfer%2Ctype%3DFileTransfer"
}
$
JvmStats
JvmStatsを取得する。
$ curl -s -k --basic -u jmxadmin:password https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3Atype%3DJvmStats/attributes | jq .
[
{
"name": "ProcessCPU",
"value": {
"value": "0.23676892201834862",
"type": "java.lang.Double"
}
},
{
"name": "GcCount",
"value": {
"value": "7",
"type": "java.lang.Long"
}
},
{
"name": "GcTime",
"value": {
"value": "78",
"type": "java.lang.Long"
}
},
{
"name": "UpTime",
"value": {
"value": "1871036",
"type": "java.lang.Long"
}
},
{
"name": "UsedMemory",
"value": {
"value": "157499176",
"type": "java.lang.Long"
}
},
{
"name": "FreeMemory",
"value": {
"value": "427606232",
"type": "java.lang.Long"
}
},
{
"name": "Heap",
"value": {
"value": "585105408",
"type": "java.lang.Long"
}
}
]
$
ThreadPoolStats
Default ExecutorのThreadPoolStatsを取得する。
$ curl -s -k --basic -u jmxadmin:password https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3DDefault+Executor%2Ctype%3DThreadPoolStats/attributes | jq .
[
{
"name": "PoolSize",
"value": {
"value": "16",
"type": "java.lang.Integer"
}
},
{
"name": "PoolName",
"value": {
"value": "Default Executor",
"type": "java.lang.String"
}
},
{
"name": "ActiveThreads",
"value": {
"value": "1",
"type": "java.lang.Integer"
}
}
]
$
SessionStats
SessionStatsを取得する。このMBeanはアプリケーション毎であり、アプリケーションが実際にセッションを使うまで作成されない。本来は自分がセッション情報をとりたいアプリケーション名を指定する必要があるが、今回はIBMJMXConnectorRESTアプリケーションを指定する。
$ curl -s -k --basic -u jmxadmin:password https://localhost:9443/IBMJMXConnectorREST/mbeans/WebSphere%3Aname%3Ddefault_host%2FIBMJMXConnectorREST%2Ctype%3DSessionStats/attributes | jq .
[
{
"name": "ActiveCount",
"value": {
"value": "0",
"type": "java.lang.Long"
}
},
{
"name": "CreateCount",
"value": {
"value": "1",
"type": "java.lang.Long"
}
},
{
"name": "LiveCount",
"value": {
"value": "0",
"type": "java.lang.Long"
}
},
{
"name": "InvalidatedCountbyTimeout",
"value": {
"value": "1",
"type": "java.lang.Long"
}
},
{
"name": "InvalidatedCount",
"value": {
"value": "1",
"type": "java.lang.Long"
}
}
]
$
ConnectionPoolStats
他に一般的にモニターしたくなりそうな情報としてはコネクションプールがある。コネクションプールはその定義を作成し、また、実際にコネクションが発生しないとMBeanが作成されないと思われる。今回は省略。
Python
PythonからローカルLibertyに接続してみる。
コード作成
Pythonスクリプトは以下の通り作成。→GitHub
#!/usr/bin/env python3
import argparse
import csv
import datetime
import logging
import os
import sys
import time
import requests
import urllib3
# 警告を非表示にする
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
formatter = '%(asctime)s %(name)-12s %(levelname)-8s %(message)s'
logging.basicConfig(level=logging.WARNING, format=formatter)
logger = logging.getLogger(__name__)
def request_with_retry(url, user, password, timeout, retry):
"""HTTPリクエストを行い、失敗した場合はリトライを行う。
:param url:
:param user:
:param password:
:param timeout:
:param retry:
:return: jsonデータ
"""
session = requests.Session()
# backoff_factorが1だとリトライの間のスリープ時間は[0s, 2s, 4s, 8s, ...]となる
retries = urllib3.util.retry.Retry(total=retry, backoff_factor=1)
session.mount('https://', requests.adapters.HTTPAdapter(max_retries=retries))
session.mount('http://', requests.adapters.HTTPAdapter(max_retries=retries))
logger.info('GET {}'.format(url))
# verify=Falseで証明書のチェックを行わない
# ただしこれだけだと警告がでるので最初にurllib3.disable_warningsをしている
response = session.get(url, auth=(user, password), verify=False, timeout=timeout)
return response.json()
def get_value(name, items):
"""辞書のリストからnameがマッチする辞書を探し、value.valueを返す。
:param name:
:param items:
:return: データの値
"""
for item in items:
if item['name'] == name:
return item['value']['value']
return None
def write_header(filepath):
"""ヘッダー書き込む。
filepathが指定され、ファイルが存在しなかった場合はファイルを作成してヘッダーを書く。
filepathが指定され、ファイルが空の場合もヘッダーを書く。
filepathが指定されなかった場合は標準出力にヘッダーを書く。
:param filepath:
:return:
"""
fieldnames = [
'Time',
'Heap', 'UsedMemory',
'PoolSize', 'ActiveThreads',
'LiveCount', 'ActiveCount']
# filepathが指定された場合
if filepath:
# ファイルが存在しない場合はファイルを作成してヘッダーを書く
if not os.path.isfile(filepath):
with open(filepath, 'w') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
# ファイルが存在する場合
else:
with open(filepath, 'r+') as csv_file:
# ファイルが空の場合はヘッダーを書く
if not csv_file.read():
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
# filepathが指定されなかった場合は標準出力にヘッダーを書く
else:
writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames)
writer.writeheader()
def append_data(filepath, jvmstats, threadpoolstats, sessionstats):
"""性能情報の値を追記する。
filepathが渡された場合はcsvに書き込み、渡されなかった場合は標準出力に書き込む。
:param filepath:
:param jvmstats:
:param threadpoolstats:
:param sessionstats:
:return:
"""
fieldnames = [
'Time',
'Heap', 'UsedMemory',
'PoolSize', 'ActiveThreads',
'LiveCount', 'ActiveCount']
item = {
'Time': datetime.datetime.now(),
'Heap': get_value('Heap', jvmstats),
'UsedMemory': get_value('UsedMemory', jvmstats),
'PoolSize': get_value('PoolSize', threadpoolstats),
'ActiveThreads': get_value('ActiveThreads', threadpoolstats),
'LiveCount': get_value('LiveCount', sessionstats),
'ActiveCount': get_value('ActiveCount', sessionstats)
}
if filepath:
# データをファイルに追記する
with open(filepath, 'a') as csv_file:
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writerow(item)
else:
# 標準出力に出力する
writer = csv.DictWriter(sys.stdout, fieldnames=fieldnames)
writer.writerow(item)
def main():
# コマンド引数の処理
parser = argparse.ArgumentParser()
parser.add_argument('--host',
action='store',
type=str,
default='localhost',
help='接続先のホスト名を指定します')
parser.add_argument('--port',
action='store',
type=int,
default=9443,
help='接続先のポートを指定します')
parser.add_argument('--interval',
action='store',
type=int,
default=10,
help='データの取得間隔(秒)を指定します')
parser.add_argument('--delay',
action='store',
type=int,
default=30,
help='モニターを開始するまでの待機時間(秒)を指定します')
parser.add_argument('--timeout',
action='store',
type=int,
default=2,
help='モニターリクエストのタイムアウト時間(秒)を指定します')
parser.add_argument('--retry',
action='store',
type=int,
default=10,
help='モニターのリトライ回数を指定します')
parser.add_argument('-f', '--filename',
action='store',
type=str,
help='出力先のファイル名を指定します')
args = parser.parse_args()
host = args.host
port = args.port
timeout = args.timeout
retry = args.retry
filepath = args.filename
# 接続ユーザーとパスワードは環境変数から取得
user = os.getenv('JMX_USER', 'jmxadmin')
password = os.getenv('JMX_PASSWORD', 'password')
# 待機時間
time.sleep(args.delay)
# ヘッダーを書く
write_header(filepath)
# MBeanのURL
jvmstats_url = 'https://{}:{}/IBMJMXConnectorREST/mbeans/' \
'WebSphere%3Atype%3DJvmStats/' \
'attributes'.format(host, port)
threadpoolstats_url = 'https://{}:{}/IBMJMXConnectorREST/mbeans/' \
'WebSphere%3Aname%3DDefault+Executor%2Ctype%3DThreadPoolStats/' \
'attributes'.format(host, port)
sessionstats_url = 'https://{}:{}/IBMJMXConnectorREST/mbeans/' \
'WebSphere%3Aname%3Ddefault_host%2FIBMJMXConnectorREST%2Ctype%3DSessionStats/' \
'attributes'.format(host, port)
# モニター
while True:
jvmstats = request_with_retry(jvmstats_url, user, password, timeout, retry)
threadpoolstats = request_with_retry(threadpoolstats_url, user, password, timeout, retry)
sessionstats = request_with_retry(sessionstats_url, user, password, timeout, retry)
append_data(filepath, jvmstats, threadpoolstats, sessionstats)
time.sleep(args.interval)
if __name__ == '__main__':
main()
- ファイル出力と標準出力への出力ができるようにした
- Libertyのコンテナの起動に時間がかかる場合を想定し、モニター開始までのdelayを設定できるようにした
- Libertyへの接続に失敗した場合にリトライをするようにした
- いくつかのパラメータを引数で設定できるようにしたが、接続ユーザーとパスワードについては環境変数から取得するようにした
実行例
$ ./monitor_restConnector.py --help
usage: monitor_restConnector.py [-h] [--host HOST] [--port PORT]
[--interval INTERVAL] [--delay DELAY]
[--timeout TIMEOUT] [--retry RETRY]
[-f FILENAME]
optional arguments:
-h, --help show this help message and exit
--host HOST 接続先のホスト名を指定します default:localhost
--port PORT 接続先のポートを指定します default:9443
--interval INTERVAL データの取得間隔(秒)を指定します default:60
--delay DELAY モニターを開始するまでの待機時間(秒)を指定します default:30
--timeout TIMEOUT モニターリクエストのタイムアウト時間(秒)を指定します default:2
--retry RETRY モニターのリトライ回数を指定します default:10
-f FILENAME, --filename FILENAME
出力先のファイル名を指定します default:未指定(標準出力)
sotoiwa@SotonoMacBook-Pro:~/workspace/liberty_monitor/monitor_restConnector (master)
$ ./monitor_restConnector.py --interval 10 --delay 0
Time,Heap,UsedMemory,PoolSize,ActiveThreads,LiveCount,ActiveCount
2019-01-13 15:43:23.679303,649592832,74171952,16,1,1,0
2019-01-13 15:43:33.753766,649592832,77029800,16,1,1,0
2019-01-13 15:43:43.830487,649592832,82213760,16,1,1,0
2019-01-13 15:43:53.907145,649592832,83140824,16,1,1,0
サイドカーとして動かす
Pythonスクリプトをコンテナ化し、Liberyコンテナのサイドカーとして動かす。
Libertyコンテナのビルド
上に記載したserver.xml
とアプリを含めてLibertyコンテナをビルドする。
FROM websphere-liberty:18.0.0.4-webProfile8
COPY --chown=1001:0 server.xml /config/
COPY --chown=1001:0 sample.war /config/apps/
ファイル配置は以下。
liberty-restconnector
├── Dockerfile
├── sample.war
└── server.xml
ビルドする。
docker build -t sotoiwa540/liberty-restconnector:1.0 .
docker push sotoiwa540/liberty-restconnector:1.0
Pythonサイドカーコンテナのビルド
Pythonのコンテナをビルドする。python
コマンドに-u
オプションをつけるか、環境変数PYTHONUNBUFFERED=TRUE
を設定しないと、標準出力がバッファされてdockerのログに出力されないことに注意。
FROM python:3-alpine
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY monitor_restConnector.py ./
ENV PYTHONUNBUFFERED TRUE
ENTRYPOINT [ "python", "./monitor_restConnector.py" ]
ファイル配置は以下。
monitor-restconnector
├── Dockerfile
├── monitor_restConnector.py
└── requirements.txt
docker build -t sotoiwa540/monitor-restconnector:1.0 .
docker push sotoiwa540/monitor-restconnector:1.0
Kubernetesへのデプロイ
パスワードを格納したSecretを作成する。
kubectl create secret generic jmx-secret --from-literal=JMX_USER=jmxadmin --from-literal=JMX_PASSWORD=password
以下のようにLiberty(with サイドカー)のマニフェストを作成。
apiVersion: apps/v1
kind: Deployment
metadata:
name: liberty-restconnector
spec:
selector:
matchLabels:
app: liberty
replicas: 1
template:
metadata:
labels:
app: liberty
spec:
containers:
- name: liberty
image: sotoiwa540/liberty-restconnector:1.0
imagePullPolicy: Always
ports:
- containerPort: 9080
- name: monitor
image: sotoiwa540/monitor-restconnector:1.0
imagePullPolicy: Always
command:
- python
- ./monitor_restConnector.py
args:
- --host
- localhost
- --port
- "9443"
- --interval
- "60"
- --timeout
- "2"
- --delay
- "30"
env:
- name: JMX_USER
valueFrom:
secretKeyRef:
name: jmx-secret
key: JMX_USER
- name: JMX_PASSWORD
valueFrom:
secretKeyRef:
name: jmx-secret
key: JMX_PASSWORD
デプロイする。
kubectl apply -f liberty-restconnector-deployment.yaml
稼働確認
LibertyのPodが稼働していることを確認。コンテナの数が2となっている。
$ kubectl get po
NAME READY STATUS RESTARTS AGE
liberty-76c9d556c9-dhmcs 2/2 Running 0 25s
$
サイドカーの方のログを確認。csvが出力できた。
$ kubectl logs -f liberty-restconnector-76c9d556c9-j2gb5 -c monitor
Time,Heap,UsedMemory,PoolSize,ActiveThreads,LiveCount,ActiveCount
2019-01-13 07:20:04.737811,72351744,68460832,6,1,1,0
2019-01-13 07:21:04.963036,72351744,61504136,4,1,1,0
TODO
SessionStatsやConnectionPoolStatsは、アプリケーションやデータソース毎にMBeanができるので、どのアプリケーションあるいはどのデータソースなのか、MBeanのURLを引数か環境変数で指定できるようにする必要がある。
また、このMBeanができるのは、実際にセッションやコネクションプールが使われてからなので、MBeanができる前にアクセスした場合に上手いこと処理が必要。