IBM Event Streams(Kafka) をInstanaを使ってモニタリングする


この記事は[Instana Observability Advent Calendar 2023](https://qiita.com/advent-calendar/2023/instana) 20日目のエントリになります。

# はじめに

Kafkaのような分散ストリーミング基盤は、コンポーネント間が疎結合になるため、システムに柔軟性をもたらしてくれます。

一方で、様々なコンポーネント間をリクエストが流れていくので、エラーや障害が発生した場合にどのコンポーネントで問題が起こっているのかを把握するのは難しいのではないでしょうか？

本記事では [IBM Instana Observability](https://www.ibm.com/jp-ja/products/instana)(以下Instana)を使用し、IBM EventStreams(≒Kafka)を使用したシステムのモニタリングをしてみようと思います。

[IBM Event Streams](https://www.ibm.com/jp-ja/products/event-streams)(以下Event Streams)はIBMが提供しているKafkaのディストリービューションです。

### 注意点

本記事では環境構築手順などは説明しておりません。

Instanaのインストール手順や、EventStreamsのインストール手順などをお探しの方は、以下のような公式ドキュメントを参照ください。

- Instana
    - https://www.ibm.com/docs/en/instana-observability
- Event Streams
    - https://ibm.github.io/event-automation/es/



# システム構成

今回は以下の構成のシステムをInstanaを使用してモニタリングします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/f1c83d6f-9afb-fb7e-a50f-8f3b1ebe9bd0.png)


### コンポーネント
本システムは以下のコンポーネントで構成されてます。

- Event Streamsクラスター
    - dev-scram-origin
    - dev-scram-target
    
    Event Streamsクラスターは２つ存在していて、`dev-scram-origin`から`dev-scram-target`に対して、Mirror Makerを構成し、トピックの同期を行っています。


- アプリケーション
    - Producerアプリ
        - nest-kafka-app
    Producerアプリは、`dev-scram-origin`のトピックに対してメッセージの送信を行います。

    
    - Consumerアプリ
        - target-nest-kafka-app
    Consumerアプリは、`dev-scram-target`のトピックからメッセージの受信を行います。
    受信するトピックは、`dev-scram-origin`からMirror Makerで複製されたトピックです。


# 検証

それでは上記のシステムに対して、実際にリクエストを行い、その結果をInstana上でみてみましょう。

## リクエストの送信

1. ProducerアプリにCURLでリクエストを送信

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/7b6af489-fe40-fd09-f642-31d73edac24d.png)

ここでは`dev-scram-origin`の`sample-topic-1`に対してメッセージを送信しています。

送信しているメッセージは、キーが`external-message`、バリューが`message send from external listener.0011`のメッセージです。

(Producerアプリケーションのドメインはマスクしてます。)

2. ConsumerアプリにCURLでリクエストを送信

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/43f2edf2-e70a-9565-e3a3-6250f4a44199.png)

ここでは`dev-scram-target`の`dev-scram-origin.sample-topic-1`トピックからデータの読み出しを行っています。

`dev-scram-origin.sample-topic-1`トピックは`dev-scram-origin`の`sample-topic-1`トピックがMirror Makerにより複製されたトピックです。

先ほど`dev-scram-origin`の`sample-topic-1`に対して送信したメッセージが読み出せていることが確認できます。

## Instana上で確認する

1. アプリケーション・パースペクティブの確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/f5b9dd0c-e2d1-fbb8-3515-2b9c67b934e1.png)

今回は上記のシステムを１つのアプリケーションパースペクティブで表示するように構成してます。

`呼び出し`のセクションを見ると先ほど実行したリクエストが記録されていることが確認できます。


2. 依存関係の確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/4e367a4f-cd07-db76-88b3-61fccf1d2b70.png)

依存関係のタブから、コンポーネント間の依存関係を確認することができます。

このグラフからコンポーネント間がシステム構成図と同じ構成で繋がっていることがわかります。

3. `呼び出しの分析`からリクエストの詳細を確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/4867980c-bd57-f355-9d21-a633d825bf46.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/6b0d70bd-4e2e-f411-5979-3dc4996bd270.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/b30c4517-8f74-9a2a-b262-1932424ebbda.png)

上記から先ほど送ったリクエストが分散トレースの形で確認できることがわかります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/5c6b623d-e78d-6dee-31f0-339e8595c242.png)

また詳細を確認したいリクエストをクリックすると、「詳細」からリクエストの詳細情報を確認することができます。

### 補足

今回はリクエスト中にエラーは発生していませんが、エラーが発生した際には「依存関係」「呼び出しの分析」画面でそれぞれ以下のようにエラー確認することができます。

1. 依存関係の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/016ba8db-2906-2795-d36a-89da504859f8.png)

[画像の引用元](https://www.apmexperts.com/cloud-monitoring/the-changing-physics-and-economics-of-monitoring/)

エラーが発生しているコンポーネントに赤く印がつきます。

エラーが発生しているコンポーネントをクリックして、ドリルダウンしていくことでより詳しい原因の調査をすることができます。

2. 呼び出しの分析の画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302134/74b5447b-fe07-8ebd-303f-663a25a4ce13.png)

[画像の引用元](https://jpn.nec.com/websam/instana/kinoulist.html)

エラーが発生しているリクエストに赤く印がつきます。

またエラーが発生しているリクエストをクリックすると、リクエストの詳細を確認することができます。

## 余談

今回ProducerアプリケーションとConsumerアプリケーションは、KafkaJS + NestJSで実装しました。

Node.jsでProducer/Consumerアプリケーションを実装して、Instanaでモニタリングしたい場合には、KafkaJSを使用するようにしてください。

kafka-nodeだとInstanaのモニタリング機能の一部がうまく動かない可能性があります。

詳しくは以下を参照ください。

https://www.ibm.com/docs/en/instana-observability/current?topic=technologies-monitoring-nodejs
>When you use the npm package kafka-node to send or consume messages. That package does not support Kafka record headers. For more information, see kafka-node#763 and kafka-node#1309. Trace continuity is supported for Kafka in general starting with Kafka version 0.11 for other runtime and also when you use the package kafkajs. Therefore, it is recommended to use kafkajs instead of kafka-node when you use Kafka and Instana in your Node.js application.


## 参考ドキュメント

- IBM Event Streamsの公式ドキュメント
    - https://ibm.github.io/event-automation/es/es_11.1/administering/cluster-health/
- Instana Monitoring Kakfa
    - https://www.ibm.com/docs/en/instana-observability/current?topic=technologies-monitoring-kafka