マイクロサービスデモ（Astronomy Shop）をSplunk Observability Cloudで可視化してみた

# はじめに

Splunk Observability Cloud（以下、Splunk o11y）でのマイクロサービスの可視化方法を説明したいと思います。

Splunk o11yはエージェントとしてOpenTelemetry（以下、Otel）を採用しており、Kubernetesに特化したSplunk [OpenTelemetry Collector for Kubernetes](https://github.com/signalfx/splunk-otel-collector-chart)を提供しています。
これを使ってサクッと可視化したいと思います。


# OpenTelemetry Demo

Otelプロジェクトが提供しているデモがあります。
これを使ってSplunk o11yへトレース送信できるようにしましょう。

https://opentelemetry.io/docs/demo/


# 構成

[こちらの図](https://opentelemetry.io/docs/)の通り、Otelはアプリに計装するためのAPI・SDKと、テレメトリーデータをバックエンドに送るためのCollectorに分かれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/e0249f8c-d2c7-b0ee-3323-291ad0b34ace.png)

通信はこのように行われます。
```mermaid
graph LR
App---OtelSDK
OtelSDK-->|OTLP/gRPC, 4317|OtelCollector
OtelSDK-->|OTLP/HTTP, 4318|OtelCollector
OtelCollector-->|HTTPS|SplunkObservabilityCloud
```

# アプリへOpenTelemetry SDK/API計装

では、まずOtel SDKはアプリからどのようにトレースデータを取得するかですが、方法は言語によります。
大まかにはAuto InstrumentationとManual Instrumentationに分かれます。

- Auto Instrumentation（自動計装）
コード自体には手をいれず、アプリ起動時のコマンドを変えることでOtel SDK/APIを動的にアプリに組み込みます。
例えばJavaであればOtel用のJava Agentをインストールし、それを引数として渡します。ホストでは通常のコマンド、コンテナであればDockerファイルに記述するのが一般的です。Auto Instrumentationにまだ対応していない言語もあります。

```sh: Java Auto Instrumentation
java -javaagent:./splunk-otel-javaagent.jar -jar <myapp>.jar
```

- Manual Instrumentation（手動計装）
Otel SDK、APIをコードに組み込みます。

なお、Auto InstrumentationとManual Instrumentationの併用は可能です。
まず利用可能な言語であればAuto Instrumentationから始めて、より詳細なデータが必要になればManual Instrumentationでトレースを追加したり、Spanに内部値（ユーザーID、テナントIDなど）をAttributeとして付与するなど拡張するがスモールスタートとしてよいと思います。

今回のデモで言語ごとにどのような計装を行っているかは以下のページにまとまっています。

https://opentelemetry.io/docs/demo/#language-feature-reference

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/e2843f03-acbd-676d-c64b-132a27e6ac92.png)




各言語の計装方法の詳細情報は[Otel公式](https://opentelemetry.io/docs/instrumentation/)、またはSplunk Otelを使う場合は[Splunk Docs](https://docs.splunk.com/Observability/gdi/get-data-in/application/application.html#nav-Instrument-back-end-services)を確認ください。


ちなみに、、、Instrumentation = 計装 = インストルメンテーション | インスツルメンテーション | インストゥルメンテーションです。
インストルメンテーションがITで、インスツルメンテーション | インストゥルメンテーションが医療でよく使われている表記のようです。
別にどれでもいいんですが私は一番書きやすく言いやすい「計装」を普段使っています。

Instrumentationとは　by ChatGPT
> インストルメンテーション（Instrumentation）は、ソフトウェアの実行時に動作や性能を監視、計測、分析するためにコードに計測用の機能を追加することを指します。特に、アプリケーションのパフォーマンスモニタリング（APM）や分散トレーシングシステムでは、アプリケーションやシステムの各部分の実行時間、呼び出し回数、エラー率などの情報を収集するためにインストルメンテーションが利用されます。



# OpenTelemetry Collectorを使用してテレメトリーデータ送信


各計装では送り先をカスタムにしない限りはデフォルトポートに送られます。

```mermaid
graph LR
OtelSDK-->|OTLP/gRPC, 4317|OtelCollector
OtelSDK-->|OTLP/HTTP, 4318|OtelCollector
```

デモはもうOtelは計装が完了しているので、後はOtel Collectorからの送り先を指定するだけです。

```mermaid
graph LR
OtelCollector-->|HTTPS|SplunkObservabilityCloud
```


まだデモを立ち上げていませんでしたね。
やっていきたいと思います。

## デモのデプロイ
Kubernetesへのデプロイ手順はこちらです。

https://opentelemetry.io/docs/demo/kubernetes-deployment/


デモではOtel CollectorやJeagerなどバックエンドも含まれていますが、今回は自前のOtelとバックエンド（Splunk o11y）を使うのでそれぞれを非活性にし、Otel SDKからCollectorへの送り先も自前用に指定します。
以下を`oteldemo.yaml`として保存します。

```yaml
default: 
  envOverrides: 
    - name: OTEL_COLLECTOR_NAME 
      valueFrom: 
        fieldRef: 
          fieldPath: status.hostIP 

opentelemetry-collector: 
  enabled: false 
jaeger: 
  enabled: false 
prometheus: 
  enabled: false 
grafana: 
  enabled: false 
```

次にhelmでインストールします。
```sh
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm install my-otel-demo open-telemetry/opentelemetry-demo --values oteldemo.yaml
```

どんなサイトが見たい場合はFrontend ProxyをExposeします。

```sh
kubectl port-forward svc/my-otel-demo-frontendproxy 8080:8080
# リモートアクセスの場合
kubectl port-forward svc/my-otel-demo-frontendproxy 8080:8080 --address 0.0.0.0
```

いい感じの天体観測ショップサイトが立ち上がりました。
なお、Loadgeneratorも作られているのでトランザクションについては自分で発生させる必要はありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/032e7aef-2ee1-e4af-4a0b-65fa648f5689.png)


## Otel Collectorのデプロイ
次に同じKubernetesクラスタにOtel Collectorをデプロイしましょう。
SplunkがOtelを機能拡張したり、Splunk o11y用に使いやすくしたOpenTelemetry Collector for Kubernetesを使います。

https://github.com/signalfx/splunk-otel-collector-chart

helmでインストールできます。Kubernetesからのテレメトリーデータ送信用設定が自動化されています。
```sh
helm repo add splunk-otel-collector-chart https://signalfx.github.io/splunk-otel-collector-chart
helm install my-local-splunk-o11y-otel-collector --set="splunkObservability.realm=<REALM名>,splunkObservability.accessToken=<アクセストークン>,clusterName=<クラスター名>" splunk-otel-collector-chart/splunk-otel-collector
```

設定のカスタム方法についてはこちら。

https://zenn.dev/symmr/articles/b7bf8daf6a3282


トレースデータからサービスマップが生成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/4d88df0b-44ad-838b-5911-19345ab0d6e3.png)

APMの使い方はこの辺りをご参照ください。

https://qiita.com/symmr/items/5388fe16db890b753c4b

https://qiita.com/symmr/items/188ddd99ff1cfc80ceb6


インフラ観点でのKubernetesのNodeやPodのモニタリングも行えています。想定外の状態（Nodeのリソース不足、DeploymentのSpecとの差異など）があればアラートも上がるようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1218403/9cb3f4c2-64d4-d1c7-655e-bdc4e97242cb.png)

なお、既にOtel Collectorが入っている場合はExporterを変えてあげればOKです。

メトリクス

https://docs.splunk.com/Observability/gdi/opentelemetry/components/signalfx-exporter.html

トレース

https://docs.splunk.com/Observability/gdi/opentelemetry/components/splunk-apm-exporter.html#nav-Splunk-APM-exporter


OpenTelemetry Collector for Kubernetesも結局はこのExpoterを使っており、その他ProcessorなどがKubernetes環境に最適化されているというものです。


# まとめ

マイクロサービスデモであるAstronomy ShopをSplunk Observability Cloudで可視化してみました。
色々ごちゃごちゃ書きましたが、計装した後、Splunk Otel Collectorを以下で入れればOKです。


```sh
git clone https://github.com/signalfx/splunk-otel-collector-chart
helm repo add splunk-otel-collector-chart https://signalfx.github.io/splunk-otel-collector-chart
helm install my-local-splunk-o11y-otel-collector --set="splunkObservability.realm=<REALM名>,splunkObservability.accessToken=<アクセストークン>,clusterName=<クラスター名>" splunk-otel-collector-chart/splunk-otel-collector
```

肝は計装です。
これはOtel以外のAPMツールでも避けられないタスクです。
ならば工数をかけるなら、標準化されておりバックエンドを自由に選べるOtelを使うのが理にかなっていると思います。