Couchbase ServerのOpenTracing互換監査機能 ~ コードを用いた解説

# はじめに

本稿では、オープンソースJSONデータベースCouchbase Serverが持つ、Open Tracing互換監査機能について、紹介します。

丁寧な解説を文章で行うことよりも、コード例を用いる事によって、最低限の時間で、基本的な内容を掴む事のできる内容を意図しています。

# 背景

Couchbaseは、ユーザーが設定した閾値に対して、応答時間がその閾値を超えていないかどうかを監視する方法を提供します。このことは、特にCouchbaseのような分散アーキテクチャーを持つシステムにおいて重要です。様々に存在する構成要素のうち、どの部分が遅延を起こしているか特定する手段が必要となるためです。こうした必要性は「Response Time Observability　（応答時間の可観測性） 」と呼ばれています。

##### 要約
**Response Time Observability（RTO）を用いたアプローチは、分散システムのトラブルシューティングに役立ちます。**

# トレーサー Tracer 入門



## トレーサーの構築

Tracerクラスを作成し、Environmentクラスへ登録することで、アプリケーションで、トレーサーを用いることができます。

```java
Tracer tracer = ThresholdLogTracer.create(ThresholdLogReporter.builder()
  .logInterval(10, TimeUnit.SECONDS) // log every 10 seconds
  .build());

CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
  .tracer(tracer)
  .build();
```

## カスタマイズとデフォルト設定

下記のように、トレーサーのデフォルトの設定を上書きすることができます（ログ出力機能確認用の例）。

```java
Tracer tracer = ThresholdLogTracer.create(ThresholdLogReporter.builder()
  .kvThreshold(1) // 1 micros
  .logInterval(1, TimeUnit.SECONDS) // log every second
  .sampleSize(Integer.MAX_VALUE)
  .pretty(true) // pretty print the json output in the logs
  .build());
```

上記の設定より、キー/バリュー操作のしきい値が1マイクロ秒に設定され、検出された操作が1秒ごとにログに記録されます。さらに、サンプルサイズとして、非常に大きな値（Integerの最大値）が設定されているため、すべてがログに記録されます。

デフォルトでは、毎分ログに記録され（何かが見つかった場合）、最も遅い操作の上位10個のみがサンプリングされます。キー/バリュー操作のデフォルトのしきい値は500ミリ秒です。

## 出力結果

```json
{
	"server_us" : 23,
	"local_id" : "41837B87B9B1C5D1/000000004746B9AA",
	"local_address" : "127.0.0.1:55011",
	"operation_id" : "get:0x1",
	"decode_us" : 1203,
	"dispatch_us" : 947,
	"remote_address" : "127.0.0.1:11210",
	"total_us" : 1525
}
```
上記のログから次のことがわかります。

- total_us：完全な操作を実行するのにかかった合計時間：ここでは約1.5ミリ（1525マイクロ）秒
- server_us：サーバーは、実行された作業に23マイクロ秒かかったと報告しています（ネットワーク時間またはクラスターで取得されるまでのバッファー内の時間は含まれません）
- decode_us：応答のデコードにはクライアントに1.2ミリ(1203マイクロ)秒かかっています。
- dispatch_us：クライアントがリクエストを送信してレスポンスを取得するまでに約1ミリ（945マイクロ）秒かかっています。
- local_address：この操作に使用されたローカルソケット。
- remote_address：この操作に使用されたサーバー上のリモートソケット。影響を受けるノードを特定するのに役立ちます。
- operation_id：操作のタイプとIDの組み合わせ。local_idと組み合わせて診断とトラブルシューティングを行うのに役立ちます。
- local_id：このIDはサーバーとネゴシエートしている際の両側のログ情報を相互に関連付けるために使用できます。

# OpenTracing互換性を用いたトレーサーの交換 （Jaeger利用）

OpenTracing互換の他のトレーサーと交換する事が可能です。
デフォルトのトレーサーをオープンソース実装のjaegerのトレーサーと交換した場合のコード例は、以下の通りです。

```java
Tracer tracer = new Configuration(
  "my_app",
  new Configuration.SamplerConfiguration("const", 1),
  new Configuration.ReporterConfiguration(
    true, "localhost", 5775, 1000, 10000)
).getTracer();

CouchbaseEnvironment env = DefaultCouchbaseEnvironment.builder()
  .tracer(tracer)
  .build();
```

Jaegerの画面は、下記のように表示されます（あくまで、雰囲気を感じていただく目的にて掲載しています）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/e36f3169-3284-cd76-c820-69ddc66eee58.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/377fffa2-4666-ccad-be7c-4151fd6844bf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/49825aad-3106-0b04-d83e-39fce74c1f8a.png)


# 最後に

冒頭に記した意図とはいえ、省略しすぎのきらいがあるかもしれませんが、本稿については、以上とさせていただきます。

# 参考情報

[Response Time Observability with the Java SDK](https://blog.couchbase.com/response-time-observability-with-the-java-sdk/)

[Jaeger: open source, end-to-end distributed tracing](https://www.jaegertracing.io/)