エンジニアリング

Elastic APMからLogstashまたはKafkaを通してデータを送信するには

今日のデプロイでは、アプリケーションサーバーの寿命が短いことや、アプリケーションサーバーがメッセージキューやデータベースなどのような他のコンポーネントよりも信頼性の低いハードウェア(プリエンプティブあるいは低優先度のVM、スポットインスタンス)を使用していることがよくあります。そのようなケースでは、より信頼性の高いシステムに早くデータを移すのがベストです。

リリース6.4.0から、APMサーバーはLogstashまたはKafkaにデータを送信し、信頼性の要件をこうしたシステムの一つに分散することができるようになります。また、Logstashを使用すると、多くの利用可能なLogstashプラグインの1つを使って、APMデータを強化することもできます。

ここで、データをElasticsearchに投入する前に別システムを通してデータを送信する場合の設定を紹介し、注意点をいくつか見ていきましょう。

  1. Elasticsearchへの出力にLogstashを設定する
  2. Elastic APMサーバーをLogstashに送信するよう設定する
  3. Elasticsearchを設定する
  4. オプションとしてソースマップを含める
  5. Kafkaを導入する

Logstashの設定

まず、パイプラインを追加して、beats/lumberjackプロトコルを使用してLogstashがAPMサーバーからイベントを受け取るよう設定し、次にそれをElasticsearchに送信します。

input {
   beats {
        id => "apm-server"
        port => 5044
  }
}
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}"
  }
}

1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 ソースマップでここにちょっとおかしな部分ができてきますが、後でこの記事内で修正します。

注意深く見ている人は、beatへのリファレンスは何をするものだろうと思うことでしょう。 APMサーバーはBeats Framework上に構築されており、従って同じメタデータがイベント内で引数を渡します。 つまり、別のBeatデータと同じLogstashインスタンス内のAPMデータ処理は、[@metadata][beat] == "apm-server"という条件文を使用して行われるということです。

APMサーバーの設定

これでLogstashが設定できたので、APMサーバーのapm-server.ymlをアップデートして、イベントをそれに応じて出力できるようにします。

output.elasticsearch:
  enabled: false
output.logstash
  enabled: true
  hosts: ["logstash:5044"]

backoff、proxy、ssl設定などの追加オプションについては、Elastic APMサーバードキュメントで詳しく説明しています。

APMサーバーで監視を有効にしている場合は、必ず次のように設定します。

xpack.monitoring.elasticsearch:
  enabled: true
  hosts: ["elasticsearch:9200"]

これで、APMサーバー自体の監視がElasticsearchに直接フローし続けるようになります。

Elasticsearchの設定

APMサーバーをスタートする準備ができるまで、あと1ステップです。 Elasticsearchはまず、APM UIが期待するとおりにAPMデータを格納する方法を知る必要があります。つまり、インデックスのテンプレートが必要だということです。 このテンプレートを読み込む方法は2通りあります。

ElasticsearchでAPMサーバーを一時的に指定することが可能なら、次のようにします。

 apm-server setup --template

それ以外の場合は、まずAPMサーバーからテンプレートをエクスポートします。

apm-server export template > apm-6.4.2.tmpl.json

それからElasticsearchに読み込みます。 curlを使って、次のようにします。

curl -XPUT -H 'Content-Type: application/json' http://elasticsearch:9200/_template/apm-6.4.2 -d @apm-6.4.2.tmpl.json

次のコマンドは、各操作が成功したか失敗したかをレポートします。 テンプレートが正常に読み込まれたか確認するには、 _template/apm-* をクエリします。 そうすると、次のようなドキュメントのセットが返されます。

{
  "apm-6.4.2": {
    "order":1,
    "index_patterns": [
      "apm-6.4.2-*"
    ],
...

インデックスパターンが、前のLogstashのステップで設定したものと合っていることに注意してください。 さらに、そこにバージョン情報が含まれていることにも注意してください。つまり、この設定ステップは次のようになるということです。

1.Logstashに接続しているAPMサーバーとまったく同じバージョンで行われる。 1.毎回APMサーバーのアップグレード中に繰り返される。

使ってみる

APMサーバーを起動して、アプリケーションの動作を分析していきましょう。

ソースマップ

ソースマップは、分かりにくいコードを元のソースに戻すマッピングのために使用されます。 一番良く見かけるのは、縮小されたJavascriptを戻すときに使われるものです。

ソースマップは、APMサーバーの出力がElasticsearchではない場合、特別な考慮が必要です。 結果的にElasticsearchにどう届くかにかかわらず、APMサーバーがこれを使うためにそこに格納されなければなりません。 ソースマッピングのストレージ設定は、rum.source_mapping.elasticsearchを次のようにセットします。

apm-server:
  rum:
    source_mapping:
      elasticsearch:
        hosts: ["elasticsearch:9200"]
        index_pattern: "apm-*-sourcemap*"

これは、APMサーバーに、apm-*-sourcemap*にマッチしたインデックスでソースマップを探すように指示しています。

ソースマップはLogstashによってアップロードすることができますが、デプロイメントプロセスの間に直接Elasticsearchに送信して、マッピングの到着が必要なイベントが起こる前に確実に格納することをおすすめします。 それができない場合は、この記事で紹介したLogstashの設定が、適用するタイミングでソースマップ取得に使用されるデフォルトのインデックスパターンに適しているので、さらに変更を加える必要はありません。

フローにKafkaを導入する

Kafkaもまた、APMサーバーからElasticsearchに送るイベント出力をバッファするときに使えます。 Kafkaを使った簡単なAPMサーバーの設定は次のとおりです。

output.kafka:
  enabled: true
  hosts: ["kafka:9092"]
  topics:
    - default: 'apm'
      topic: 'apm-%{[context.service.name]}'

ここでは1サービスに1トピックの使用をお見せしていますが、必須ではありません。 ドキュメントには、他の構成オプションも記載されています。

イベントがKafkaにフローすれば、これをElasticsearchにプルできるようLogstashを設定することができます。 たとえば以下のようにします。

input {
  kafka {
    id => "apm-server-kafka"
    bootstrap_servers => ["kafka:9092"]
    topics_pattern => "apm.*"
    codec => "json"
  }
}
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}"
  }
}

ここでも、1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 Logstash Kafka出力プラグインのその他の方法は、ドキュメントで紹介しています。

Give it a try

APMサーバーには、LogstashやKafkaを使用したAPMデータ送信に対する柔軟性があります。 ぜひお試しになり、ディスカッションフォーラムにご意見をお寄せください。 皆さんのアイデアも、いつでも歓迎しています。どうぞ自由にソースコードをご覧になり、問題を報告したりリクエストしたりしてください。