OpenTelemetry のバックエンドとしてDynatraceを使ってみる

# はじめに

アプリケーション開発においてオブザーバビリティを実現するために[OpenTelemetry](https://opentelemetry.io/)を使用するケースが増えているように感じます。
OpenTelemetry自体はテレメトリーデータの生成、収集、管理、出力にフォーカスしており、そのデータを処理しUIを提供するバックエンドのシステムはJaegerやPrometheusのようなOSS製品からDynatraceをはじめとした商用ベンダーまでさまざま利用が可能です。
本記事では、バックエンドとしてDynatraceを用いる方法について紹介します。

# 環境

Kubernetes環境にOpenTelemetry DemoアプリとOpenTelemetry CollectorをデプロイしてCollector経由でDynatraceへデータを送る方法について試していきます。

[OpenTelemetry Demoアプリ](https://opentelemetry.io/docs/demo/)

demoアプリ、CollectorともにHelmを使ってインストールしていきます。
デフォルトで用意されているHelm Chartを利用すると全てAll-in-oneでインストールすることができますが、今回はdemoアプリとCollectorで異なるNamespaceにインストールしていきたいと思います。

絵にするとこんな感じです。Ingress等も使って良い感じに外からアクセスできるようにしていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/13ee341e-2b8b-6afd-de27-5aba4bec25c6.png)

ちなみにKubernetes環境はUbuntu上にMicrok8sで構築しています。

Dynatraceへのテレメトリーデータの送信はActiveGateを経由させていますが、Dynatraceへ直接送信する方法もサポートしています。

:::note info
DynatraceといえばOneAgentを使ったデータの収集が代表的ですが、今回はCollector経由のみでどのようなデータが収集できるか確認したいためOneAgentは導入しません。
:::

# Dynatrace環境の準備

## ActiveGateの構築（オプション）

[この辺の記事](https://qiita.com/sukatsu1222/items/7f07122544453253eb4c)を参考にActiveGateを構築します。

OTLPのエンドポイントは以下のアドレスになります。

`https://{your-activegate-domain}:9999/e/{your-environment-id}/api/v2/otlp`

## アクセストークンの発行

Dynatraceへデータを取り込むにあたって必要なアクセストークンは以下の3つになります。

| シグナル   | アクセススコープ             |
|:----------|:-----------------------------|
| トレース   | `openTelemetryTrace.ingest` |
| メトリクス | `metrics.ingest`            |
| ログ       | `logs.ingest`               |

DynatraceのUIからアクセストークンの発行画面に行き、トークン名を入力して、**スコープの検索**に`opentelemetry`と入力すると必要なトークンの一覧が出てきますので3つ全てにチェックを入れて**トークンの生成**をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/2a3f434f-9f55-4b1b-6271-5794946f12cf.png)

生成されたトークンは一度しか表示されないため、必要に応じて安全に保存してください。

# OpenTelemetry Collectorのデプロイ

[この辺](https://github.com/open-telemetry/opentelemetry-helm-charts/tree/main/charts/opentelemetry-collector)を参考にCollector用の`values.yaml`を作成します。

```opentelemetry-collector/values.yaml
mode: deployment

config:
  exporters:
    otlphttp/dynatrace:
      endpoint: https://{your-activegate-domain}:9999/e/{your-environment-id}/api/v2/otlp
      tls:
        insecure_skip_verify: true
      headers:
        Authorization: "Api-Token dt0c01.XXXXX"

  service:
    pipelines:
      traces:
        exporters: [otlphttp/dynatrace]
      metrics:
        exporters: [otlphttp/dynatrace]
      logs:
        exporters: [otlphttp/dynatrace]

resources:
  limits:
    cpu: 250m
    memory: 512Mi
```

DynatraceはOpenTelemetry ProtocolのHTTPを利用したバイナリーエンコーディング方式にネイティブ対応していますので、`otlphttp`を指定することが可能です。

`helm install`コマンドでCollectorのインストールを実行します。

# OpenTelemetry Demoのデプロイ

[この辺](https://github.com/open-telemetry/opentelemetry-helm-charts/blob/main/charts/opentelemetry-demo/examples/bring-your-own-observability/values.yaml)を参考にCollectorやバックエンドがいないDemoアプリ用の`values.yaml`を作成します。

```values.yaml
default:
  envOverrides:
    - name: OTEL_COLLECTOR_NAME
      value: my-otel-collector-opentelemetry-collector.otel-col

components:
  frontendProxy:
    ingress:
      enabled: true
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt
        kubernetes.io/ingress.class: public
      hosts:
        - host: otel-demo.example.com
          paths:
            - path: /
              pathType: Prefix
              port: 8080
      tls:
        - hosts:
          - otel-demo.example.com
          secretName: otel-demo-tls

opentelemetry-collector:
  enabled: false

jaeger:
  enabled: false

prometheus:
  enabled: false

grafana:
  enabled: false
```

本筋とは関係ないですが、cert-managerを使ってTLSでデモアプリにアクセスできるように設定してあります。

デプロイに成功したらアクセスできるか確認をしておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/c8d104c3-0466-07d5-8b1b-dce584dbaa99.png)

# Dynatraceでのデータの確認

## サービスと分散トレースの確認

DynatraceのUIから**サービス**を開いてみます。無事にデータが届いていることが確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/4b6d8f66-1064-add7-809f-7f6d8db477eb.png)
checkoutserviceが応答時間の中央値、90パーセンタイルともにかなり時間がかかっているようなのでもう少し深堀して分散トレースを確認してみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/b62f28bb-a1c6-5fa0-9ce1-b85e6106adab.png)
トポロジー情報もちゃんと取れていますね。[デモアーキテクチャの図](https://opentelemetry.io/docs/demo/architecture/)によれば、Checkout Serviceはいろんなサービスの起点になっているのがわかりますが、Dynatraceの画面上でもそれが確認できますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/f55fbde5-415e-a4d7-b651-c01acd91eb08.png)
分散トレースの画面では、`orders publish`の処理にかなり時間がかかっていることがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/7b08a761-3eed-eb53-7272-fbdec2c6c1c9.png)
メタデータやAttribute情報もしっかり取れていそうです。
右上にある`このトレースのログを表示`ボタンをクリックしてみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/d8512539-930b-6bb3-a6bb-ae712cb39438.png)
自動的でクエリを書いてくれてトレースIDと紐づいたログを表示してくれるので便利ですね。

## 疑似障害の発生

デモアプリケーションは[Feature Flags](https://opentelemetry.io/docs/demo/feature-flags/)を変更することで疑似的にエラーを発生させることが可能なようです。せっかくなので、試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/be8beb74-d958-5ccc-ead4-98a42f7fdd66.png)

adServiceFailureという障害を発生させてみたいと思います。Enabledを1に設定することで常に発生（10回に1回の割合でエラーが起きる）します。

しばらくするとDynatrace側でもFailed requestsの値が上昇していることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/e74c4ce2-532b-5d98-70c2-ab5414e8cc4c.png)

失敗状態の分散トレースのみ抽出してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/d4ad0d0c-8271-456f-8568-cf189ae949a3.png)

該当のスパンのイベント情報では`exception.message	RESOURCE_EXHAUSTED`が確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/8a9ff00f-d500-27c4-c56c-cc08ab3d255b.png)

また、スパンに紐づいて出力されているログ情報も確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/051cd89b-a245-f1c4-0a13-ec5e2d70dc9d.png)

Failure rate increaseのプロブレムが上がっていることも確認できました。アラート通知の設定をしていればメールやSlackなどに通知することが可能ですので、障害にすぐに気づけそうですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65441/2235700a-6599-b395-e385-85e11a2a0d28.png)

# まとめ

今回はOpenTelemetry Demoアプリを使って、オブザーバビリティバックエンドにDynatraceを利用することでどのようにデータが確認できるのか試してみました。
Collector経由でも普通に使うことはできそうですし、障害の検知も問題なくできました。