Tanzu ObservabilityでDBの通信を可視化する

Tanzu ObservabilityでDBの通信の可視化ができるようになりました。すごい。

はじめに

Tanzu Observability(以降TO)のRelease 2020-38.0が公開されました。 久しぶりの大型アップデートなのですが、分散トレーシングにAmazonのサービスやDBの通信が可視化されるという機能が追加されました。

もともとこのシリーズ第6回目にも取り上げていましたが、TOの分散トレーシングはHTTP通信の可視化以外に、AMQPの通信の可視化も行えていました。ただDBに関しては、まだ直感的にわかるものは提供がされていなく、欠落している状態でした。

今回のアップデートでDBの通信の可視化も行えるようになり、いよいよTOがアプリケーション監視にフルに使えるようになっていくのでは思っています。

今回はその方法を紹介していきます。

前提

準備

以下をインストールした端末を用意してください。

  • Java JDK 8+

Oracle JDKに従いJDKをインストールしてください。

これ以外にもPostgresqlを端末にインストールして、ユーザー名/パスワードなどの初期設定をしてください。下記を参考にしてください。

https://www.postgresql.org/docs/9.3/tutorial-install.html

なお、必要なのはユーザー作成とデータベースまでです。テーブルはコードから自動で生成させます。

ソースコード

以下に公開しています。

https://github.com/mhoshi-vm/wavefront-ext-dt

とりあえず、試してみる

コードの解説を後回しして、とりあえず、早速起動してみます。 まず上のソースコードをダウンロードします。

1git clone https://github.com/mhoshi-vm/wavefront-ext-dt
2cd wavefront-ext-dt

次にsrc/main/resources/application.propertiesを環境に合わせ更新します。 特にspring.datasource.urlspring.datasource.usernamespring.datasource.passwordは環境に合わせ変更ください。

1wavefront.application.name=my-app
2wavefront.application.service=my-service
3
4spring.datasource.driver-class-name=org.postgresql.Driver
5
6spring.datasource.url=jdbc:postgresql://localhost:5432/example-db
7spring.datasource.username=spring
8spring.datasource.password=spring

この状態でアプリケーションを起動します。

1./mvnw spring-boot:run

初回は起動に時間がかかるかもしれませんが気長にまってください。 最後に表示されるURLはあとでアクセスするので保管してください。

 12020-11-11 23:02:51.824  INFO [,,,] 919 --- [           main] c.e.p.PostgreSluethApplication           : Started PostgreSluethApplication in 4.131 seconds (JVM running for 4.379)
 2
 3Your existing Wavefront account information has been restored from disk.
 4
 5To share this account, make sure the following is added to your configuration:
 6
 7	management.metrics.export.wavefront.api-token=XXXXXX
 8	management.metrics.export.wavefront.uri=https://wavefront.surf
 9
10Connect to your Wavefront dashboard using this one-time use link:
11https://wavefront.surf/us/XXXXXX

そうしたら、別プロンプトを起動して、以下のコマンドでいったんリクエストを投げ続けてください。

1watch curl -sS localhost:8080/car

コードが正しく実行されていれば、以下のように出力されるはずです。

1[{id=1, name=Avalon}, {id=2, name=Corolla}, {id=3, name=Crown}, {id=4, name=Levin}, {id=5, name=Yaris}, {id=6, name=Vios}, {id=7, name=Glanza}, {id=8, name=Aygo}]

5分ほどまったら、先ほどのURLにアクセスしてください。 以下のような画面が表示されるはずです。

すでにお洒落な画面で気になるかもしれないですが、ここではなく、上位のタブから [Applications] > [Application Status]を確認してください。

すると、以下のようにアプリケーションとDBの接続情報がみれるようになると思います。

成功です。すごい。

解説編

さて、 Tanzu Observabilityでは、どうやってこのDBのトレーシング情報をみているか、以下のマニュアルに記載されています。

https://docs.wavefront.com/tracing_external_services.html

簡単に説明すると、以下のようになります。

  • DBの表示は通常の分散トレーシングの仕組みと大差ない
  • TO上では、送信されるSPANの「あるタグ」からDBのトレースかを識別している

ここでいう「あるタグ」というのは、以下の3つです。

  • component: どのアプリケーションで接続するか?執筆時点では"java-jdbc"に固定
  • db.type: どのようなDBか?postgreslやOracleなど
  • db.instance: TO上でどういう名前で表示させるか

つまり、これらのタグをもったスパンさえ送ることができれば、TO側では自動で描写されます。 なお上のドキュメントでは、専用のSDKを使うよう案内されていますが、仕組みさえ分かってしまえば、今回のサンプルアプリの用、Spring BootのSluethなど標準のライブラリーでも実装できます。

今回のコードの要になるのが以下の部分です。

https://github.com/mhoshi-vm/wavefront-ext-dt/blob/main/src/main/java/com/example/postgreslueth/PostgreSluethApplication.java#L36-L49

 1String performSql(String SQL) {
 2  Span newSpan = this.tracer.nextSpan().name("postgres").start();
 3  try {
 4    newSpan.tag("component", "java-jdbc");
 5    newSpan.tag("span.kind", "client");
 6    newSpan.tag("db.type", "postgresql");
 7    newSpan.tag("db.instance", "localDB");
 8    List<Map<String, Object>> list;
 9    list = jdbcTemplate.queryForList(SQL);
10    return list.toString();
11  } finally {
12    newSpan.finish();
13  }
14}

[Applications] > [Traces]を開くと、それらのタグをもったスパンが確認できるようになります。

みての通り、SQLを実行するたびに任意のスパンの生成およびタグを追加しています。 なお、例えば、db.typeを他のDBにすれば、以下のように表示されます。残念ながら、Oracleのアイコンにはまだならないので、すこし寂しいですが。。。

残念なことに「まったくコードをいじらなくてよい」というまではいかないですが、みての通りかなりシンプルにつくれます。私自身がコーディング力が高くないですが。。。もうすこし作り込めば、関数の共通化などそこまで意識することなくスパンの付与ができるかと思います。

そして、何より!うれしいのがここまでの全ての機能が無料でできること。さすがTO太っ腹!

まとめ

TOの新機能のDBのトレーシング情報は結構簡単に実装でき、アプリケーション監視の幅を広げます。