🔭

ターミナルでOpenTelemetryのトレースを閲覧できるツール「otel-tui」を作りました

2024/06/26に公開

少し前に比べるとだいぶOpenTelemetry界隈もにぎやかになってきたなーと感じる今日この頃です。私も2年ほど前からコントリビュートしたりブログ記事を書いたりしていましたが、どこかで同期的に開催されるイベントにも参加したいなーと思っています。

さて、皆さんは普段アプリケーションを計装したり計装用のライブラリを書く際は、ローカルでの動作確認をどのように行っているでしょうか?

自身の観測範囲内ではローカルでjaegerやGrafanaなどを上げている人が多い印象ですが、今回新たな方法としてターミナル上でOpenTelemetryを閲覧できる自作ツール「otel-tui」をご紹介できればと思います。

https://github.com/ymtdzzz/otel-tui

なお、今回の記事では使い方などユーザー向けの内容となっているので、実装周りの詳細については下記のブログ記事をご参照ください。

https://ymtdzzz.dev/post/view-otel-with-otel-tui/

モチベーション

ローカルでの開発に「ちょうど良い」ツールがほしかった

これまでの自身の経験から、ローカルでシグナルを出力して確認したいユースケースとしては下記のようなものがありました。

  • トレースが意図したとおり紐付いているか確認したい
    • contextの欠落など実装レベルの動作確認を行いたい場合
  • 想定通りのattributeが設定されているか確認したい
    • ベンダー側で指定したattributeがついてないと上手く表示されない場合
    • 独自のattributeを指定している場合

現状、ローカルでシグナル(主にトレース)の確認をする方法として下記が挙げられると思います。

  • ローカルにjaeger(all-in-oneなどUI付きのもの)やGrafana Tempoコンテナを上げて送信&閲覧する
  • Exporterを活用して標準出力やファイルなどに出力し確認する

ただ、これらの方法には下記の限界があります(自分は普段ローカルでjaeger立ててました)。

ローカルにjaeger(all-in-oneなどUI付きのもの)やGrafana Tempoなどのコンテナを上げて送信&閲覧する

  • ローカルで動かすにはそれなりに重い
  • productionレベルの機能群がtoo muchすぎる(サービスマップなど)
  • リアルタイムに出力内容をサクサク閲覧する みたいなのがしにくい

Exporterを活用して標準出力やファイルなどに出力し確認する ※こちらはやったことないので想像です

  • 可読性が低い(トレース紐付け状態などはTrace IDやparent Span ID等でgrepするなど)

このように、production gradeの製品をコンテナで動かすのはtoo muchすぎるし、テキストベースだと閲覧しにくい・・・ということで、それぞれいいとこ取りできるようなツールが欲しいなと思ったのがきっかけです。

類似ツールもあるけれど

このツールを作成するきっかけにもなった「otel-desktop-viewer」があります。このツールもローカルでOpenTelemetryで出力されたシグナルを閲覧することにフォーカスしたもので非常に使いやすいです。

ただ、ある程度の流量を長時間流し続けるとクエリや画面描画にもたついたりする(※マシンスペックによる)ことがあり、自分としてはブラウザを開かずにリアルタイムで閲覧でき、かつパフォーマンス的にも安定した自分好みのツールを作りたくなりました。

特徴・機能

画面はこんな感じです。

<Trace>

<Log>

主な特徴や機能は下記の通りです。

  • 機能面
    • トレース
      • サービススパン単位のリスト表示及びサービス名による検索
      • Attributeなどの詳細情報表示
      • トレースのグラフ表示(waterfall diagram)
    • ログ
      • ログのリスト表示及び検索
      • ログから該当トレースへのジャンプ
  • パフォーマンス
    • 軽量かつリアルタイムの画面更新(シグナル受信と画面描画の非同期化)
    • 長時間ある程度の流量を流し続けてもメモリリークしない(データローテーション)

TODOs

逆に、まだ足りてない機能もたくさんあります

  • 柔軟な設定
    • 画面更新頻度
    • バッファーサイズ
  • メトリクス取得と表示
  • 挙動の安定性
    • ごくまれに長時間利用しているとプロセスが落ちたり
  • 一貫したキーバインド
  • UI周り
    • ナビゲーション
      • トレース→ログ詳細→元のトレースに戻るなど
    • テキストの折返し、waterfall diagram
    • デバッグログ

使い方

せっかくなのである程度の流量を体験できる「opentelemetry-demo」から出力されるシグナルを用いて使い方をご紹介できればと思います。

「otel-tui」のインストール

Homebrewでインストールできます。

$ brew install ymtdzzz/tap/otel-tui

Homebrew以外のパッケージ管理ツールにはまだ対応していないので、Homebrewが利用できない場合リリースページからバイナリを落としていただくか、ソースからビルドしてください。

helpやversionが出ればOKです。

$ otel-tui -v
otel-tui version 0.1.2

$ otel-tui -h
Usage:
  otel-tui [flags]

Flags:
      --grpc int      The port number on which we listen for OTLP grpc payloads (default 4317)
  -h, --help          help for otel-tui
      --host string   The host where we expose our all endpoints (OTLP receivers and browser) (default "0.0.0.0")
      --http int      The port number on which we listen for OTLP http payloads (default 4318)
  -v, --version       version for otel-tui

計装済みアプリの向き先変更

今回は「opentelemetry-demo」を使うのでリポジトリをクローンし、必要な設定を行います。

Collectorの向き先修正

opentelemetry-demoは複数のマイクロサービスで構成されていますが、すべてのシグナルはOpenTelemetry Collectorに集約されています。そのため、Collectorのexporterの向き先をotel-tuiに向けるだけでOKです。

# src/otelcollector/otelcol-config-extras.yml
exporters:
  otlp:
    endpoint: host.docker.internal:4317

service:
  pipelines:
    traces:
      exporters: [spanmetrics, otlp]
    logs:
      exporters: [otlp]

コンテナからホストのポートへの通信を許可 ※Docker Desktop以外の場合のみ

LinuxなどDocker Desktopを利用していない場合、host.docker.internalをコンテナ内部から解決できるように設定してあげます。

  # docker-compose.minimal.yml
  # OpenTelemetry Collector
  otelcol:
    image: ${COLLECTOR_CONTRIB_IMAGE}
    container_name: otel-col
		# ...
    extra_hosts:
      - "host.docker.internal:host-gateway"

otel-tuiと計装済みアプリを起動

それぞれ別タブなどで起動します。

# otel-tuiのパスが通っているところならどこでも
$ otel-tui
# opentelemetry-demoリポジトリのroot
$ make start-minimal

データを探索する

少しするとotel-tui上で、先述したような画面でずらずらとシグナルが流れてくるかと思います。

トレースとログはTabキーで切り替えが可能で、各ペインもタイトル(Details(d)など)に記載のあるキーを入力することで移動することが可能です。

ちょっと多すぎるなということで/キーで検索ボックスに移動し、productとかで検索(Enterキー)してみます。

productというprefixのサービスに関連するスパンにフィルタリングされました。Detailsペインに現在フォーカスされているSpanのリソース情報、属性などの情報が表示されています。ちなみに、Detailsペインにフォーカスした状態でEnterキーを押下するとツリーを折りたたみ可能です。

TracesペインでフォーカスしているSpanをEnterキーで選択すると、トレース詳細画面に飛びます。

Trace Timelineでは実装の都合上矢印キーのみでの操作となります(他はhjklでも操作可能)。これまたフォーカスするとDetailsに詳細情報が出てきます。Logsペインには当該トレースに関連性のあるログが出てきます。

Escキーでトレース一覧に戻り、Tabキーでログ画面に切り替えてみます。

トレースと同じように適当なワードで検索を行いつつ、Detailsを見てみるとLogRecord>trace idにリンク絵文字(🔗)が付与されているものがあります。

そのAttributeにフォーカスを合わせてEnterキーを押下すると、該当のトレース詳細画面に遷移することが可能です。

このように、計装したアプリから想定通りの情報が渡ってきているか、きちんと紐付いているかなど実装観点での動作確認に役立てることができます。

さいごに

まだまだ機能も足りなく荒削りな部分が多いですが、個人的には割と結構使いやすくて気に入っています。

使ってみた方は是非issueやXなどでフィードバックいただけますと幸いです!

Discussion