LogstashからWildflyのJMX情報を取得する

# はじめに

LogstashからWildflyのJMX情報を取得する環境を構築して試してみます。


# 環境

使用した環境は以下のとおり。

- CentOS 7.5
- Elasticsearch 7.8
- Kibana 7.8
- Logstash 7.8
- Wildfly 20.0.1.Final

「[ElasticStack 7.8 環境構築](https://qiita.com/mkyz08/items/d4eb9f20efbd9dc77547)」で構築した環境を利用しています。


# WildflyをリモートからJMXで接続できるように設定する

リモートからJMXへ接続できるようにWildflyを設定します。
以下の設定ファイルを修正します。

- $JBOSS_HOME/standalone/configuration/standalone.xml

まず、リモート構成を許可するため、以下のように[use-management-endpoint="true"]を追加します。

```xml:standalone.xml
       <subsystem xmlns="urn:jboss:domain:jmx:1.3">
            <expose-resolved-model/>
            <expose-expression-model/>
            <remoting-connector use-management-endpoint="true"/>
        </subsystem>>
```

次にリモート接続を許可するため、以下のように修正します。
"192.168.10.126"は環境に合わせて、外部から接続できるIPアドレスを指定します。

```xml:standalone.xml
    <interfaces>
        <interface name="management">
            <inet-address value="${jboss.bind.address.management:192.168.10.126}"/>
        </interface>
        <interface name="public">
            <inet-address value="${jboss.bind.address:192.168.10.126}"/>
        </interface>
    </interfaces>
```

最後にWildflyを起動します。
起動後、jconsoleを使用して外部から接続できることを確認します。
jconsoleでWildflyに接続する場合、以下のようにjboss-cli-client.jarを指定する必要があります。
以下の例はWindowsから接続する場合のコマンドです。

```
%JAVA_HOME%/bin/jconsole -J-Djava.class.path=%JAVA_HOME%/lib/tools.jar;%JAVA_HOME%/lib/jconsole.jar;C:\jboss-cli-client.jar
```

jconsoleで新規接続先を指定します。ユーザー名とパスワードはWildflyであらかじめ作成したユーザーを指定します。

- service:jmx:remote+http://192.168.10.126:9990

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179607/ffb261cf-3da6-8c7d-b811-85a0e9b1c16f.png)

接続できるとjconsoleは以下のように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179607/44227598-528f-f344-f809-3cdc37853cf8.png)


# Logstashの設定

まず、logstash-input-jmxをインストールするために、以下のコマンドを実行します。

```
# /usr/share/logstash/bin/logstash-plugin install logstash-input-jmx
```

実行後、Wildfly JMX用の設定を作成します。設定は以下の公式サイトを参考に実施しました。

- [Jmx input plugin](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jmx.html)

```
# vi /etc/logstash/conf.d/wildfly-jmx.conf

input {
  jmx {
    path => "/etc/logstash/jmx"
    polling_frequency => 60
    type => "jmx"
    nb_thread => 4
  }
}
output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "wildflyjmx-%{+YYYY.MM.dd}"
  }
}
```

上の設定でJMXの接続、取得するデータを記載する設定のパスを指定しました。（/etc/logstash/jmx）
以下のようなJSONファイルを新規に作成します。

"url"と"host"が重複していますが、両方設定しないとエラーになったのでそのままにしています。
本当は"url"がなくても接続できるはずなのですが、Wildflyの場合はプロトコルにremote+httpを使用しているためか、このような設定になっています。
queriesの部分がJMXで取得するデータになります。

```json:/etc/logstash/jmxconf
    {
      "url": "service:jmx:remote+http://192.168.10.126:9990",
      "host" : "192.168.10.126",
      "port" : 9990,
      "username" : "testadmin",
      "password": "XXXXXXXX!",
      "alias" : "wildflyserver1",
      "queries" : [
      {
        "object_name" : "jboss.as.expr:data-source=ExampleDS,subsystem=datasources,statistics=pool",
        "attributes" : [ "ActiveCount", "AvailableCount" ],
        "object_alias" : "DataSource.Pool"
      } ]
    }
```

設定後、logstashコマンドで設定が正しいかを確認します。

```
# /usr/share/logstash/bin/logstash --config.test_and_exit -f /etc/logstash/conf.d/wildfly-jmx.conf
[INFO ] 2020-08-03 10:48:03.357 [LogStash::Runner] Reflections - Reflections took 84 ms to scan 1 urls, producing 21 keys and 41 values 
Configuration OK
[INFO ] 2020-08-03 10:48:03.922 [LogStash::Runner] runner - Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash
```

問題がなければ、logstashコマンドで起動してみます。

```
# /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/wildfly-jmx.conf 
```

ここで以下のエラーが発生しました。

```
[ERROR] 2020-08-04 05:23:25.083 [Ruby-0-Thread-15: :1] jmx - Unsupported protocol: remote+http
[ERROR] 2020-08-04 05:23:25.084 [Ruby-0-Thread-15: :1] jmx - javax.management.remote.JMXConnectorFactory.newJMXConnector(javax/management/remote/JMXConnectorFactory.java:359)
```

remote+httpがサポートされていないというエラーのようです。
jconsoleで接続した際にjboss-cli-client.jarを指定したので、同様に設定して起動したところエラーが解消されました。

```
# export LS_JAVA_OPTS=-Xbootclasspath/a:/opt/wildfly-20.0.1.Final/bin/client/jboss-cli-client.jar
# /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/wildfly-jmx.conf 
```


# KibanaでJMXで取得した情報を表示する

Kibanaの[Discover]で確認すると、以下のように取得した情報が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179607/e2209174-4d0b-4ced-af19-be8b7cbea219.png)

ただし、[Jmx input plugin](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jmx.html)に以下のように記載がありましたが、metric_value_numberではなくmetric_value_stringになってしまいました。原因不明。

> When returned metrics value type is number/boolean it is stored in metric_value_number event field otherwise it is stored in metric_value_string event field.



# 参考

- [Remote JMX access to WildFly (or JBoss AS7) using JConsole](https://dzone.com/articles/remote-jmx-access-wildfly-or)
- [JMX MBean サーバー接続の有効化](https://www.ibm.com/support/knowledgecenter/ja/SSMKFH/com.ibm.apmaas.doc/install/jboss_config_agent_prereq_enable_server_connections.htm)