Logstash愛をマシマシにする方法

# はじめに

これは、[Elastic Stack (Elasticsearch) Advent Calendar 2019](https://qiita.com/advent-calendar/2019/elasticsearch)の18日目の記事です。

17日目はRettyの@r4-keisukeさんによる[「Elasticsearch 2.x から 7.xへの道」](https://qiita.com/r4-keisuke/items/65e5f434652e5e32b6c0)でした。

今日は、一部の人からはエビフライの人と呼ばれる[Elastic Certified Engineer](https://training.elastic.co/exam/elastic-certified-engineer)ではないド素人の私が、Logstashを愛でるためのTipsをご紹介しますぞ！
余計な修飾語が多いので話半分に読み進めて、ゆっくりしていってね！！！！


## よくあるLogstashの不満

やっぱりLogstashが好き、と[もたいまさこ](https://ja.wikipedia.org/wiki/%E3%82%82%E3%81%9F%E3%81%84%E3%81%BE%E3%81%95%E3%81%93)みたいなことをおっしゃる方がいたのです。

でも、私にはそこまでのLogstash愛がない。愛を取りもどせではないですが、
Logstash愛を**マシマシ**[^マシマシ]に、いや全マシにする方法を考えようと思いました。

みなさま、何に一番ご不満があるでしょうか。

[^マシマシ]: マシマシのイメージを画像で得たい方は、[こちらのブログ](https://blog.goo.ne.jp/fukunao0716)がとても参考になります。

私と同じ悩みがあるとすれば・・・
それはきっと、**起動が遅い**こと。これに尽きるのではないでしょうか。


一度起動さえしてしまえば、あとは安定して動くとは言えど、開発途中や検証中においては毎回毎回起動に時間がとられるのは、ストレスの元です。禿げます。勢いあまってリクルートキャリアに登録しかねません。

設定ファイルがあっているかを試すだけでも遅いです。玄関開けたら2分でご飯というフレーズがありますが、そのぐらいのスピード感が欲しいのです。
これを解決しなければ愛は取り戻せません。You are shock. 天に帰るときが来たのだ。

## もう苦情は既に上がっている

このあたりのissueが該当する内容です。

- Why is Logstash so slow to start?
    - https://github.com/elastic/logstash/issues/5507
- Logstash startup still too slow
    - https://github.com/elastic/logstash/issues/10943

世の中、だいたいみんな同じところで悩むんだなぁと分かってホッコリしますが、まだCloseされてません。つらいですね。


## じゃあ、どうすべきか

issue5507、この中に重要なヒントが入っています。

**Improving startup time**
https://github.com/jruby/jruby/wiki/Improving-startup-time

JRubyのドキュメントですが、Improving startup timeとピンポイントなことが書かれています。

ここで書かれている内容を、Logstashのjvm.optionsに書くとよさそうです。

先のIssue5507のスレッドの中で、このような書き込みがありましたので、これを適用しましょう。

> @guylando you can recreate --dev flag with these lines in your jvm.options file.

```
-Djruby.compile.invokedynamic=false
-Djruby.compile.mode=OFF
-XX:+TieredCompilation
-XX:TieredStopAtLevel=1
```

https://github.com/elastic/logstash/issues/5507#issuecomment-437426736


--devフラグ相当のものを指定すればよい、と読めました。ピザでも食ってろ--devと。モグモグ風林火山。


## jvm.optionsの変更

jvm.optionsは、$LS_HOME/config/jvm.optionsにあるファイルを変更することで指定できますな。

```
# Turn on JRuby invokedynamic
# ↓ 既定値ではtrueになっているため、コメントアウト
#-Djruby.compile.invokedynamic=true
# Force Compilation
-Djruby.jit.threshold=0
# Make sure joni regexp interruptability is enabled
-Djruby.regexp.interruptible=true

# はやくなれー
-Djruby.compile.invokedynamic=false
-Djruby.compile.mode=OFF
-XX:+TieredCompilation
-XX:TieredStopAtLevel=1
```

今回、指定したい４つの設定項目のうち、１つ`-Djruby.compile.invokedynamic'が初期値でtrueとなっていますが、
今回設定したい値はfalseなので、間違わないようにコメントアウトもしておきましょう。

## 実測

実測方法は、elastic社が提供しているLogstashのDockerイメージを使用し、コンテナからLogstashのconfig.test_and_exitを実行し、完了するまでの時間を計測します。
それぞれ20回計測します。テストは順番に行い、複数のテストが同時に実行されないようにし、同時間帯に他の作業はしないものとしました。

### テスト環境

- Microsoft Azure VM
    - Standard D2s v3 (2 vcpu 数、8 GiB メモリ)
    - Ubuntu

### jvmオプション変更した方のテスト

このような形で、jvm.configを外部から渡すようにしました。
Logstashでテストする設定ファイル文字列は、-e オプションで指定しました。

```
function testForJvmOptions() {
	SECONDS=0

	docker run --rm -it \
        -v $(pwd)/jvm.options:/usr/share/logstash/config/jvm.options \
        docker.elastic.co/logstash/logstash:7.5.0 \
        logstash -e 'input {} filter {} output {}' --config.test_and_exit

	echo "ただいまの処理時間 = ${SECONDS}" >> result.log
}

```

ノーマルの設定値のものは、-vオプションを削っただけのものとします。

```
function testForNormalOptions() {
	SECONDS=0

	docker run --rm -it \
        docker.elastic.co/logstash/logstash:7.5.0 \
        logstash -e 'input {} filter {} output {}' --config.test_and_exit

	echo "ただいまの処理時間 = ${SECONDS}" >> result.log
}

```

### 結果

得られたファイルをまとめると、下表のようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111676/a0c4d087-500a-725d-951a-a3623d918531.png)

だいぶ起動～終了までの時間が、目に見えて短縮されていることが実感できるかと思います。
約3倍です。MS-06Sもビックリな差です。

## まとめ

jvm.optionsを本番環境で運用する際には、しっかり見直す内容かと思います。

しかし、メインのLogsatash用の設定ファイルを、せっせと作っている間は、何度も実行する必要があったりするわけで、
設定ファイルが正しいかどうか、そのための環境であれば、ぜひお試しして良いオプションかと思います！


## おまけ

こちらのPullRequestをご覧ください。

**「Changed: base JRUBY_OPTS to default to --dev (for 'fast' scripts) #11355」**
https://github.com/elastic/logstash/pull/11355

すでにmasterに取り込まれていることから、次のLogstashがリリースされるころには --devオプションがデフォルトで設定されていることになるかと思います。
--devを指定すると、今回指定したjvm.optionsの内容が反映されるとのこと。
このPRでは、Windows用のバッチファイルには何の手も入ってないところが、いささか気になりますが・・・。


それはさておき、以上のことから言えることは、このAdvent Calendarの内容は、そのバージョンがリリースされるまでの間しか役立たないということです！！！
せめて年内は賞味期限があると思う！　良かった、今日までに新バージョンがリリースされなくて！！！間に合った！

ではごきげんよう！　
明日のAdvent Calendarのご担当は@j-yamaさんです、ご期待ください~