Elastic APMでWildflyで稼働するアプリケーションのパフォーマンスを監視する


はじめに

Elastic APMを使用して、Wildflyで稼働するアプリケーションのパフォーマンスを監視する環境を構築してみます。

環境

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

  • CentOS 7.5
  • Elasticsearch 7.8
  • Kibana 7.8
  • APM Server 7.8
  • APM Java Agent 1.18.0.RC1
  • Filebeat 7.8
  • Wildfly 20.0.1.Final

Elasticsearch/Kibana/Elastic APMは、「ElasticStack 7.8 環境構築」で構築した環境を利用しています。

WildflyにAPM Agentを設定する。

アプリケーションのパフォーマンスに関する情報を取得するAPM AgentをWildflyに設定します。

まずはJava用のAPM Agentを以下からダウンロードします。

今回ダウンロードしたのは「elastic-apm-agent-1.18.0.RC1.jar」になります。
ダウンロードしたモジュールはWildflyが起動するサーバの適当な場所に格納します。

次にWildflyに対してAPM Agentの設定を行います。設定方法は以下の公式サイトを参考にして実施します。

Wildflyの設定ファイル(standalone.conf)に以下の設定を追加します。各変数の値については環境やアプリケーションに合わせて適切に設定する必要があります。

# vi /opt/wildfly-20.0.1.Final/bin/standalone.conf

export JAVA_OPTS="$JAVA_OPTS -javaagent:/opt/elastic-apm-agent-1.18.0.RC1.jar"
export JAVA_OPTS="$JAVA_OPTS -Delastic.apm.service_name=my-cool-service"
export JAVA_OPTS="$JAVA_OPTS -Delastic.apm.application_packages=org.example,org.another.example"
export JAVA_OPTS="$JAVA_OPTS -Delastic.apm.server_urls=http://localhost:8200"

設定が終わったらWildflyを起動するだけで完了です。

Kibana APM UIでパフォーマンスに関する情報を確認する

Kibana APM UIでパフォーマンスに関する情報を確認してみます。
Kibanaの左側のメニューから「APM」を選択し、サービスを指定すると以下のように分散トレーシングが表示できます。

この分散トレーシングのトレース情報とログを関連付けることもできます。
つぎはこの関連付けの設定を実施します。

Elasticsearch用のログフォーマットでログを出力する

Elasticsearchに取り込むためのJSONのログフォーマットでログを出力するようにWildflyの設定を変更します。

以下の公式サイトを参考に実施します。

まず、アプリケーションのpom.xmlに以下の内容を追加します。
これはJBoss Log Manager用のECS(Elastic Common Schema)形式のログを出力するためのFomatterです。

        <dependency>
            <groupId>co.elastic.logging</groupId>
            <artifactId>jboss-logmanager-ecs-formatter</artifactId>
            <version>0.5.0</version>
        </dependency>

これにより"jboss-logmanager-ecs-formatter-0.5.0.jar"と"ecs-logging-core-0.5.0.jar"がダウンロードされます。この2ファイルはWildflyに登録するので、アプリケーション側ではなくても動きます。そのため、ダウンロードしたらpom.xmlからは削除しても構いません。

次にWildflyの設定を変更します。
公式サイトの手順ではjboss-cli.shを使用して変更していたのですが、今回はstandalone.xmlを直接変更しています。
手順のとおりに実施するなら以下のようなコマンドになります。この場合、Logstashへ直接ログを送信することになるのですが、一旦ファイル出力し、Filebeatで送信する方式にしたかったので実行していません。

# ./jboss-cli.sh --connect --controller=192.168.10.126:9990 -c 'module add --name=co.elastic.logging.jboss-logmanager-ecs-formatter --resources=/opt/jboss-logmanager-ecs-formatter-0.5.0.jar:/opt/ecs-logging-core-0.5.0.jar --dependencies=org.jboss.logmanager'
# ./jboss-cli.sh --connect --controller=192.168.10.126:9990 -c '/subsystem=logging/custom-formatter=ECS:add(module=co.elastic.logging.jboss-logmanager-ecs-formatter, class=co.elastic.logging.jboss.logmanager.EcsFormatter, properties={serviceName=my-app}),/subsystem=logging/console-handler=CONSOLE:write-attribute(name=named-formatter,value=ECS)'

関係するモジュールを以下に格納します。場所は適当です。

/opt/jboss-logmanager-ecs-formatter-0.5.0.jar
/opt/ecs-logging-core-0.5.0.jar

以下の設定ファイルのログに関する部分を、ECSフォーマットで別のログファイル(server_json.log)へ出力するように修正します。

  • /opt/wildfly-20.0.1.Final/standalone/configuration/standalone.xml
# vi /opt/wildfly-20.0.1.Final/standalone/configuration/standalone.xml

        <subsystem xmlns="urn:jboss:domain:logging:8.0">
            <periodic-rotating-file-handler name="logstash-handler" autoflush="true">
                <formatter>
                    <named-formatter name="ECS"/>
                </formatter>
                <file relative-to="jboss.server.log.dir" path="server_json.log"/>
                <suffix value=".yyyy-MM-dd"/>
                <append value="true"/>
            </periodic-rotating-file-handler>
            <root-logger>
                <level name="INFO"/>
                <handlers>
                    <handler name="CONSOLE"/>
                    <handler name="FILE"/>
                    <handler name="logstash-handler"/>
                </handlers>
            </root-logger>
            <formatter name="ECS">
                <custom-formatter module="co.elastic.logging.jboss-logmanager-ecs-formatter" class="co.elastic.logging.jboss.logmanager.EcsFormatter">
                    <properties/>
                </custom-formatter>
            </formatter>

なお、修正した内容は以下のファイルに自動で反映するようです。

  • /opt/wildfly-20.0.1.Final/standalone/configuration/logging.properties

Wildflyの設定ファイル(standalone.conf)に以下の設定を追加します。

# vi /opt/wildfly-20.0.1.Final/bin/standalone.conf

export JAVA_OPTS="$JAVA_OPTS -Delastic.apm.enable_log_correlation=true"

FilebeatでWildfly(ECS)のログをElasticsearchへ送信する

FilebeatでWildfly(ECS)のログをElasticsearchへ送信するように設定します。
/etc/filebeat/filebeat.ymlを以下のように修正します。

/etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /opt/wildfly-20.0.1.Final/standalone/log/server_json.log
  json.keys_under_root: true
  json.overwrite_keys: true
output.elasticsearch:
  hosts: ["localhost:9200"]

設定後、以下のコマンドでFilebeatを再起動します。

# systemctl stop filebeat
# systemctl start filebeat

Kibanaでログを確認する

アプリケーションのトレースは以下のように表示されています。ここからトレースのトランザクションに対応するログを表示します。

Transaction detailsから[Host logs]を選択します。

選択すると、トランザクションに対応するログが表示されます。

逆にログから[View in APM]を選択すると、ログに対応するトランザクションのトレースを表示することができます。