CLOVER🍀

That was when it all began.

Infinispan 9.4.1.Finalで追加された、Prometheus Exporterを試す

これは、なにをしたくて書いたもの?

  • Infinispan 9.4.1.Finalで、Prometheus向けにメトリクスがエクスポートできるようになったらしい
  • 正確には、Infinispan Serverで使える
  • せっかくなので、試してみようと

Infinispan: Infinispan 9.4.1.Final and Infinispan Spring Boot Starter 2.1.0.Final are out!

Infinispan Server & Prometheus JMX Exporter

Infinispan Serverの起動時にオプションを加えることで、Prometheus向けのExporterが起動するようです。

具体的には、JMX Exporterが起動します。9779ポートを使って起動するようです。

ドキュメントはまだない…ので、このあたりの情報を見つつ。

GitHub - prometheus/jmx_exporter: A process for exposing JMX Beans via HTTP for Prometheus consumption

https://github.com/infinispan/infinispan/blob/master/server/integration/feature-pack/src/main/resources/content/bin/standalone.sh#L24-L30

https://github.com/infinispan/infinispan/blob/master/server/integration/feature-pack/src/main/resources/content/bin/standalone.sh#L126-L128

https://github.com/infinispan/infinispan/blob/9.4.9.Final/server/integration/feature-pack/src/main/resources/content/bin/prometheus.sh#L17

JMX Exporterは、JMXの情報からPrometheus向けにメトリクスをエクスポートすることができるライブラリですね。JavaAgentとして
使用します。

JMX Exporterについては、以前にエントリを書きました。

PrometheusのJMX Exporterを試す - CLOVER🍀

というわけで、Infinispan ServerにPrometheus JMX Exporterの設定ファイルが含まれるようになっています。

https://github.com/infinispan/infinispan/blob/master/server/integration/feature-pack/src/main/resources/content/bin/prometheus_config.yaml

内容的には、JMXの情報をこの4つに絞り、

whitelistObjectNames: 
  - "jboss.datagrid-infinispan:type=Cache,name=*,manager=*,component=Statistics"
  - "jboss.datagrid-infinispan:type=Cache,name=*,manager=*,component=Cache"
  - "jboss.datagrid-infinispan:type=Cache,name=*,manager=*,component=ClusterCacheStats"
  - "jboss.datagrid-infinispan:type=Cache,name=*,manager=*,component=StateTransferManager"

メトリクスの名前を短くしたりと、加工しているようですね。1度取得してみるとわかりますが、「datagrid_〜」みたいな
メトリクス名で取得することになります。
※ClusterCacheStatsやStateTransferManagerは、クラスタリングしないと現れません

Infinispanで取得できるJMXの情報は、こちらを見るとよいでしょう。

JMX Components

JConsoleなどで直接MBeanを見るとわかりますが、いくつか取得できる種類のうち、Cacheにのみ絞られていることと、
かつCacheから取得できる情報も一部に絞られていることがわかります。

f:id:Kazuhira:20190311155104p:plain

f:id:Kazuhira:20190311155115p:plain

ポイントは、まずはこれくらいでしょうか。では、実際にInfinispan ServerでPrometheus向けのJMX Exporterを有効にして
みましょう。

Infinispan ServerをJMX Exporterを有効にして起動する

今回の環境は、こちらです。

$ java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-8u191-b12-2ubuntu0.18.04.1-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

Infinispan Serverは、9.4.9.Finalを使用します。ダウンドードして展開。

$ wget http://downloads.jboss.org/infinispan/9.4.9.Final/infinispan-server-9.4.9.Final.zip
$ unzip infinispan-server-9.4.9.Final.zip
$ cd infinispan-server-9.4.9.Final

起動には、「--jmx」オプションを有効にして起動します。

$ bin/standalone.sh --jmx

するとまあ、こんな例外を出力してコケてしまいます。

15:54:32,777 INFO  [org.jboss.modules] (main) JBoss Modules version 1.8.6.Final
java.lang.IllegalStateException: The LogManager was not properly installed (you must set the "java.util.logging.manager" system property to "org.jboss.logmanager.LogManager")
    at org.jboss.logmanager.Logger.getLogger(Logger.java:57)
    at org.jboss.as.server.Main.main(Main.java:89)
    at org.jboss.modules.Module.run(Module.java:352)
    at org.jboss.modules.Module.run(Module.java:320)
    at org.jboss.modules.Main.main(Main.java:593)
15:54:33,089 FATAL [org.jboss.as.server] (main) WFLYSRV0239: Aborting with exit code 1

エラーメッセージにあるとおりに、「-Djava.util.logging.manager=org.jboss.logmanager.LogManager」を追加してもうまくいきません。
ちなみにこれ、調べてみたところ、Infinispan Server 9.4.3.Finalまでは「--jmx」オプションだけで起動していたんですよ。

どうしたものかなぁとちょっと調べてみたら、こういうエントリを見つけたので

Hawkular - Running Hawkular Agent

参考に試してみたら、起動しました…。

$ JBOSS_MODULES_SYSTEM_PKGS=org.jboss.byteman,org.jboss.logmanager bin/standalone.sh --jmx

もともと「--jmx」を付けたら「JBOSS_MODULES_SYSTEM_PKGS」も調整していてくれたのが、Java 11で起動しないという
問題に対応する時に、なくなってしまったようです。

if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then if [ "x$JBOSS_MODULES_SYSTEM_PKGS" = "x" ]; then
   JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman,org.jboss.logmanager.LogManager"       JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman"
   if [ $USE_JMX_COLLECTORS ]; then 
    JBOSS_MODULES_SYSTEM_PKGS="org.jboss.byteman,org.jboss.logmanager"  
   fi   
fi

ISPN-9797 Ensure the server starts with the correct JDK modules if ne… by tristantarrant · Pull Request #6505 · infinispan/infinispan · GitHub

https://github.com/infinispan/infinispan/commit/d9866a12c5dcdf17365f9df2070c33a13c2a9252#diff-57c1d150bc430a0dc87fbe09847d9922

かといって、Java 11で「--jmx」をつけて起動した場合には違う問題が出るんですけどね…。

$ java -version
openjdk version "11.0.2" 2019-01-15
OpenJDK Runtime Environment (build 11.0.2+9-Debian-3bpo91)
OpenJDK 64-Bit Server VM (build 11.0.2+9-Debian-3bpo91, mixed mode, sharing)

$ JBOSS_MODULES_SYSTEM_PKGS=org.jboss.byteman,org.jboss.logmanager bin/standalone.sh --jmx

  JAVA_OPTS:  -server -Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Djava.net.preferIPv4Stack=true -Djboss.modules.system.pkgs=org.jboss.byteman,org.jboss.logmanager -Djava.awt.headless=true  --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED --add-exports=jdk.unsupported/sun.reflect=ALL-UNNAMED --add-modules=java.se -Djava.util.logging.manager=org.jboss.logmanager.LogManager -Xbootclasspath/p:/opt/infinispan-server-9.4.9.Final/modules/system/layers/base/org/jboss/logmanager/main/jboss-logmanager-2.1.4.Final.jar -Xbootclasspath/p:/opt/infinispan-server-9.4.9.Final/modules/system/layers/base/org/wildfly/common/main/wildfly-common-1.4.0.Final.jar -javaagent:/opt/infinispan-server-9.4.9.Final/modules/system/add-ons/ispn/io/prometheus/jmx/ispn-9.4/jmx_prometheus_javaagent-0.3.1.jar=9779:bin/prometheus_config.yaml

=========================================================================

-Xbootclasspath/p is no longer a supported option.
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

「-Xbootclasspath/p」…遠い…。今回はこのままいきましょう…。

先ほどのとおり、「JBOSS_MODULES_SYSTEM_PKGS」に「org.jboss.logmanager」を追加すれば、Prometheus向けの
Exporterが有効になります。

## スタンドアロンで起動する場合は、こちら
$ JBOSS_MODULES_SYSTEM_PKGS=org.jboss.byteman,org.jboss.logmanager bin/standalone.sh --jmx

## クラスタを構成する場合、こちら
$ JBOSS_MODULES_SYSTEM_PKGS=org.jboss.byteman,org.jboss.logmanager bin/standalone.sh --jmx -c clustered.xml

今回はSingle Nodeですが、clustered.xmlを使った構成でいきます。

ちなみに、「--jmx」の後ろにパスを付けてあげると、PrometheusのJMX Exporter向けの設定ファイルとして解釈されます。

$ JBOSS_MODULES_SYSTEM_PKGS=org.jboss.byteman,org.jboss.logmanager bin/standalone.sh --jmx my_prometheus_config.yml

メトリクスが取得できるか、確認してみます。

$ curl -s localhost:9779 | grep datagrid | head -n 10
# HELP datagrid_state_transfer_manager JMX MBean StateTransferManager
# TYPE datagrid_state_transfer_manager untyped
datagrid_state_transfer_manager{attribute="join_complete",container="clustered",name="org.infinispan.CLIENT_SERVER_TX_TABLE",} 1.0
datagrid_state_transfer_manager{attribute="state_transfer_in_progress",container="clustered",name="org.infinispan.CLIENT_SERVER_TX_TABLE",} 0.0
datagrid_state_transfer_manager{attribute="join_complete",container="clustered",name="repl",} 1.0
datagrid_state_transfer_manager{attribute="state_transfer_in_progress",container="clustered",name="repl",} 0.0
datagrid_state_transfer_manager{attribute="join_complete",container="clustered",name="org.infinispan.CONFIG",} 1.0
datagrid_state_transfer_manager{attribute="state_transfer_in_progress",container="clustered",name="org.infinispan.CONFIG",} 0.0
datagrid_state_transfer_manager{attribute="join_complete",container="clustered",name="___protobuf_metadata",} 1.0
datagrid_state_transfer_manager{attribute="state_transfer_in_progress",container="clustered",name="___protobuf_metadata",} 0.0

Cacheにもアクセスしてみましょう。REST Cacheにアクセスするために、アプリケーションユーザーを追加。

$ bin/add-user.sh -a -u ispn-user -p password

データの登録、取得。

$ curl -i -u ispn-user:password -XPUT localhost:8080/rest/default/key1 -d 'value1'
HTTP/1.1 200 OK
connection: keep-alive
etag: 282873
content-length: 0

$ curl -i -u ispn-user:password localhost:8080/rest/default/key1
HTTP/1.1 200 OK
connection: keep-alive
etag: 282873
last-modified: Thu, 1 Jan 1970 09:00:00 +0900
content-type: application/octet-stream
content-length: 6

value1

メトリクスの確認(いくつか抜粋しています)。

$ curl -s localhost:9779 | grep datagrid | grep default

datagrid_cache_stats{attribute="hits",container="clustered",name="default",} 1.0
datagrid_cache_stats{attribute="read_write_ratio",container="clustered",name="default",} 2.0
datagrid_cache_stats{attribute="stores",container="clustered",name="default",} 1.0
datagrid_cache_stats{attribute="number_of_entries",container="clustered",name="default",} 1.0

それっぽい値が表示されました。

あとは、Prometheus側にScrapeの設定を入れます。Prometheusは、2.7.2を使用しています。
prometheus.yml

global:
  scrape_interval:     5s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 5s # Evaluate rules every 15 seconds. The default is every 1 minute.

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']
  - job_name: 'infinispan-server'
    static_configs:
    - targets: ['192.168.0.2:9779']

この部分ですね。

  - job_name: 'infinispan-server'
    static_configs:
    - targets: ['192.168.0.2:9779']

PrometheusのWeb Consoleで、認識されているか確認。

f:id:Kazuhira:20190311163805p:plain

PromQL で絞り込んでみましょう。

datagrid_cache_stats{name="default",attribute=~".*hits.*|.*ratio.*|.*remove.*|stores"}

f:id:Kazuhira:20190311163928p:plain

表示できました、と。

まとめ

Infinispan Serverで、JMX Exporterを有効にして動作確認してみました。

現在のバージョンでも、Java 8で動かすのにちょっと細工が必要だったり、Java 11では怪しかったりといろいろあるようですが、
とりあえずどういうものか確認はできましたと。

起動まわりのところは、どう見ていこうかなぁ…。

Fluentdで、Apacheのアクセスログを読み込んで、複数の出力先(output)を扱うことを考える

これは、なにをしたくて書いたもの?

Fluentdを使って、ひとつのinputから複数のoutputに出力する練習に、と。

こちらのエントリの変形版です。

Fluentdで、Apacheのアクセスログを読み込んで、内容によって出力先(output)を振り分けることを考える - CLOVER🍀

お題

Fluentdを使って、Apacheのアクセスログをtailして読み込み、複数の出力先に対して出力することを考えます。
出力先は、Elasticsearchと標準出力(Fluentdのログ)とします。

環境

Ubuntu Linux 18.04 LTS上で行い、Fluentdのバージョンは以下とします。

2019-03-10 16:47:02 +0000 [info]: starting fluentd-1.3.3 pid=1125 ruby="2.4.5"

元ネタと同じく、Apacheは同じ環境上でインストール。Apacheで公開するコンテンツは、Apache自身のドキュメントとしています。

$ sudo apt install apache2 -y
$ sudo systemctl start apache2.service
$ cd /var/www/html/
$ sudo wget https://www-us.apache.org/dist//httpd/docs/httpd-docs-2.4.33.en.zip
$ sudo unzip httpd-docs-2.4.33.en.zip
$ sudo mv httpd-docs-2.4.33.en/* ./.

Apacheのバージョンは、こちらです。

[Sun Mar 10 14:07:04.729072 2019] [mpm_event:notice] [pid 600:tid 140156732517312] AH00489: Apache/2.4.29 (Ubuntu) configured -- resuming normal operations

FluentdがApacheのアクセスログを読み込めるように、ディレクトリおよびファイルの権限変更。

$ sudo chmod 755 /var/log/apache2
$ sudo chmod 544 /var/log/apache2/*

Elasticsearchは、6.6.1で別ホスト(172.17.0.3)で用意。

Fluentdの設定をする

では、Fluentdの設定を行います。

Apacheのアクセスログの読み込みにはtail、パースにはapache2プラグインを使用しています。

Output Pluginには、まずはcopyを使用。

copy Output Plugin | Fluentd

copyプラグインは、複数の出力先にイベントをコピーできるプラグインです。

/etc/td-agent/td-agent.conf

<source>
  @type tail
  @id input_tail
  <parse>
    @type apache2
  </parse>
  path /var/log/apache2/access.log
  pos_file /var/log/td-agent/apache2-access.log.pos
  tag apache.access
</source>

<match apache.access>
  @type copy
  @id access_log_copy

  <store>
    @type stdout
    @id output_access_log_stdout
  </store>

  <store>
    @type elasticsearch
    @id output_access_log_elasticsearch
    host 172.17.0.3
    port 9200
    index_name access-log
  </store>
</match>

出力先はstore(複数可)内に書くことができ、今回はstdoutとelasticsearchを使用しています。

<match apache.access>
  @type copy
  @id access_log_copy

  <store>
    @type stdout
    @id output_access_log_stdout
  </store>

  <store>
    @type elasticsearch
    @id output_access_log_elasticsearch
    host 172.17.0.3
    port 9200
    index_name access-log
  </store>
</match>

storeの中には、Output Pluginの設定をそのまま書くようです。

stdout Output Plugin | Fluentd

Elasticsearch Output Plugin | Fluentd

ドキュメントを見ていると、formatやbufferも書くことができるようですね。

Example Configuration

また、routeプラグインやラベルと組み合わせた例も。

Routing Examples | Fluentd

この設定で、Fluentdを再起動します。

確認

あとは、Apacheにアクセスして確認してみます。

Fluentdのログファイルには、こんな感じでログが出力されます。

2019-03-10 17:15:49.000000000 +0000 apache.access: {"host":"172.17.0.1","user":null,"method":"GET","path":"/","code":200,"size":2502,"referer":null,"agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
2019-03-10 17:15:49.000000000 +0000 apache.access: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/manual-zip.css","code":200,"size":862,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
2019-03-10 17:15:49.000000000 +0000 apache.access: {"host":"172.17.0.1","user":null,"method":"GET","path":"/style/css/prettify.css","code":200,"size":1443,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}
2019-03-10 17:15:49.000000000 +0000 apache.access: {"host":"172.17.0.1","user":null,"method":"GET","path":"/images/feather.png","code":200,"size":21433,"referer":"http://172.17.0.2/","agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"}

〜省略〜

Elasticsearchにも、(Bufferがフラッシュされた後に)同じようにログが入ります。

$ curl '172.17.0.3:9200/access-log/_search?q=*&pretty'
{
  "took" : 4,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 11,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "access-log",
        "_type" : "fluentd",
        "_id" : "WFCbaGkBfPGZ7ujxf7Ep",
        "_score" : 1.0,
        "_source" : {
          "host" : "172.17.0.1",
          "user" : null,
          "method" : "GET",
          "path" : "/",
          "code" : 200,
          "size" : 2502,
          "referer" : null,
          "agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
        }
      },
      {
        "_index" : "access-log",
        "_type" : "fluentd",
        "_id" : "XVCbaGkBfPGZ7ujxf7Ep",
        "_score" : 1.0,
        "_source" : {
          "host" : "172.17.0.1",
          "user" : null,
          "method" : "GET",
          "path" : "/style/scripts/prettify.min.js",
          "code" : 200,
          "size" : 13428,
          "referer" : "http://172.17.0.2/",
          "agent" : "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36"
        }
      },

〜省略〜
      }
    ]
  }
}

これで、ひとつのログから複数のOutputへ出力できることを確認できました、と。