OpenCensus meetup vol.1参加レポート

こんにちは、獏良天の風神こと@garsueです。 MF KESSAIでバックエンドのエンジニアをやってます。

先日、OpenCensus meetup vol.1にブログ枠として参加しました。 今回はそのイベントレポートとぼくなりの感想を書いていこうと思います。

OpenCensus meetup

マイクロサービスやサーバーレスアーキテクチャなど、複雑化・分散化していく昨今のシステムでは、システム全体の状態を把握することが困難になってきました。 フロントエンド、クライアントサイドも年々複雑になっていますが、バックエンド以上に状態を観測することが困難です。

システム全体のいつ・どこで・何が・どうなっているかを把握できるようにすること、すなわちオブザーバビリティ(Observability、可観測性)1の担保が課題になっています。

その課題解決の一助となる技術としてOpenCensus2が注目されています。

しかし、まだよく知らない・気になっているという人が大部分ということもあり、実際にOpenCensusを使っている人を中心に情報交換をする場としてOpenCensus meetupが開催されました。

OpenCensus meetup opening

最初に登壇したのは主催者の@ymotongpooさん。GoogleでStackdriverを担当しているOpenCensusの最先端にいる方です。

トレースやメトリクスをとっているか、OpenCensusを知っているかというアンケート結果を踏まえて、OpenCensusのノウハウ共有とコミュニティの活性化を目的にイベントを開催したそうです。

OpenCensus界隈で流行る自己紹介の仕方や、ハッシュタグ#opencensusjpをたくさん使ってみんなで盛り上げようという一体感が生まれました(笑)。

オブザーバビリティ全般についてわいわい話すDiscordも紹介してくださいました。 ご興味のある方は参加してみてはいかがでしょう。

https://discord.gg/ufkayEV

OpenCensus Intro and Status Update

オープニングからの流れで@ymotongpooさんによるOpenCensusのイントロダクション、そしてこれからどうなっていくのかという話に。

OpenCensusとは「サービスのメトリクスと分散トレースを取得するためのライブラリ群」です。

アプリケーションからトレースやメトリクスの情報を受けるクライアントライブラリと、それをStackdriverやDatadogなどのバックエンドへ渡すExporterから構成されています。 これによりメトリクスやトレースの取得について、特定のAPMのクライアントライブラリに依存せず抽象化できます。

DBなどのミドルウェア製品のクライアントライブラリに対してOpenCensusを予め仕込んだ(pre-instrumented)ライブラリも提供されています。 たとえばRedisのクライアントライブラリをpre-instrumentedのものに差し替えるだけで、Redisの操作にどれだけ時間がかかっているかわかる、といった具合です。

他にもメトリクスとして投げるViewというデータの構成や、集めたデータをブラウザで確認できるzPagesの紹介もありました。 OpenCensusはまだまだこれからだと思っていましたが、すでに導入のためのハードルは結構低そうだなと感じました。

そしてOpenCensusのこれからの話へ。

現在OpenCensus ServiceというOpenCensusをサービス化(daemon化)した形で利用できるように開発が進んでいるそうです。

OpenCensus Serviceは今の所OpenCensus AgentとOpenCensus Collectorの2種類のサービスが考えられています。

OpenCensus AgentはExporterをサービスとして切り出したもので、クライアントライブラリからはOpenCensus Agentに投げるだけ、という構成にするものです。 現状はアプリケーション内に特定のバックエンド向けのExporterを組み込んで使用する形になっているため、クライアントライブラリの初期化に特定バックエンド向けの接続情報などを含める必要があります。 OpenCensus Agentを使えばバックエンドについてすべてOpenCensus Agentに任せることができるため、アプリケーションはもはやバックエンドについて何も知らなくて良くなります3

例えばアプリケーションのコードを変えずに開発環境、本番環境のバックエンドを切り替えたりなど、かなり便利そうですね。 コンテナデザインパターンで言うところのSidecarパターンとしてもハマりそうなので、Kubernetesなどオーケストレーションツールを使っている場合もキレイに導入できそうです。

OpenCensus CollectorはExporterやOpenCensus Agentからトレースやメトリクスのデータを受け取り、それをバックエンドやまた別のOpenCensus Collectorに送信するサービスです。 データを受け取ってから送信するまでの間で、バッファリング、リトライ、サンプリングレートの調整などもできるようです。 ちょっとまだイメージがつかめていませんが、OpenCensus Collectorを出口として、細かい調整や高度な変換処理を一元管理できるのは魅力的です。

OpenCensus Serviceはまだ絶賛開発中で安定して利用できるのはまだ先になりそうですが、場合によってはOpenCensusの使い方が変わってくる可能性もありそうだなという印象を受けました。 引き続きウォッチしていきたいですね。

また、OpenCensusと利用ドメインのかぶっていたOpenTracingとの統合も発表されました。 が、現状はそういう方向性が示されただけで、今すぐどうこうという話ではないようです。 ぼくはOpenTracingについて何も知らない分際ですが、分散トレースについてせっかくオープンにやっているのだし、それぞれ分断されるよりいいのではないかなと思っています。

OpenCensusを実際に使ってみて、便利なところと、困ってるところ

メルペイの@sinmetalさんの発表です。 GCPUGで積極的に活動している方で、プライベートでも業務でもGCPを活用しているそうです。

その経験から、StackdriverをバックエンドとしたOpenCensusの実践的な話をしてくださいました。

GCPのクライアントライブラリはいわばpre-instrumentedになっていて、明示的に仕込まなくてもトレースを取れるそうです。 GKE内の別サービス呼び出しのトレースを仕込んだ際、firestoreへの読み書きのトレースが勝手に出てきたとのことでした。 GCPユーザーはすぐに恩恵を受けられるので嬉しいですね。

一方でたまにしか起きないパフォーマンスの低下のようなレアケースを拾うのは困難だそうです。 試しにサンプリングをやめて全件トレースしようとしたところ、buffer fullになって結局全件トレースできずという悲しい話も……。 こういった低頻度の事象を追うのにトレースを使うのはあまり向いていなそうですね。

また、トレースを取っても、得られたSpanが表している時間の見方についても注意すべきという話もありました。 Span内のネットワークIOなどをボトルネックとして疑いがちですが、実際はCPUがカツカツだったりロジックに問題があったりなど他に原因がある場合もあります。

トレースだけを手がかりとせず、メトリクスと合わせて見たり、処理対象のデータサイズをSpanのメタデータに埋めるなどしてメタデータを充実させたりするのも手だとのことです。 非常に実践的な知見で参考になりました。

Distributed Tracing with OpenCensus at Wantedly

Wantedlyでinfrastructure teamに所属している@munisystemさんの発表です。

Wantedlyは多様な言語やプラットフォームを利用しているPolyglotな環境だそうです。 さらに近年マイクロサービス化をすすめていて、サービスをまたいだ分散トレースが必要になってきたとのこと。

そこで複数言語のサポートもあり、バックエンドも差し替え可能なOpenCensusを採用することに。 オープンな技術であるため、そこで生まれるエコシステムにうまく乗っていくことも狙いのひとつだそうです。

バックエンドはDatadogとStackdriver Traceを併用しているそうですが、いずれ統一させたいそうです。 複数バックエンド構成を取れるのも何気にOpenCensusのいいところですね。

OpenCensusは社内の共通ライブラリに入れ込んで、各サービス側では共通ライブラリ経由で利用する構成らしいです。 弊社も似たようなものがあるのでなんとなくイメージできます。

WantedlyではGoとRubyを使っているそうですが、RubyのOpenCensusサポートはあまり充実していないため、なんと自分たちでバグ修正や機能追加して使っているそうです。 パワーありますね!

ここから徐々に運用面の話に。

実際に埋め込んでるメタデータの内容や使用しているプロパゲーションフォーマットの紹介、サンプリングレートの設定の話もありました。 検索時の使い勝手など運用時のことも意識した作りにすることが大事ですね。

現状の課題として、バックエンド固有のアトリビュートをpre-instrumentedなクライアントライブラリによって作られたSpanに設定する口がないという問題を挙げていました。 クライアントライブラリ側がHookを用意してアトリビュートを入れる口がないといけないのですが、現状それがなかったので直接手を入れたとのこと。

また、現状Exporterがバックエンドのクライアントライブラリに密に依存しているので、片方のみのバージョンを上げられないそうです。 このあたりはOpenCensus Serviceによってアプリケーションが直接バックエンドのクライアントライブラリへ依存しなくて済む構成になると良いですね。

OpenCensus Javaで始めるOpenCensus

JavaやScalaコミュニティで活動なさっている@grimroseさんの発表です。

データエンジニア視点で、OpenCensusのJava実装について話してくださいました。

OpenCensusのJava実装は実はAndroid Compatibleをうたっているとのこと。 サーバーサイドの分散トレースやメトリクスの話になりがちですが、クライアントサイドもOpenCensusでカバーしていきたいですね。

Javaの他のトレーシング実装の違いとして、javaagent経由でトレーシングできるものが多いことを挙げていました4。 classファイルのバイトコードを操作してトレースを取るコードを差し込むようです。JVMならでは、といったところでしょうか。

Java界隈はZipkin利用率が高いらしく、ZipkinをサポートしているExporterが多いとのこと。 それに伴いプロパゲーションフォーマットもB3 propergation対応が多いらしいです。

Springに特化した実装や、Servletに特化した実装もあるそうです。 これは嬉しい人が多そうですね。

逆にこれら以外のフレームワークを使っている場合は独自で頑張る必要があるとのこと。 nettyとかだと辛いんでしょうかね……?

Scopeの書き方としてはCloseableに準拠しているのでtry with resourcesを使うと良いそうです。 なるほどと思いつつ、deferで済むGoは楽だなと改めて思いました。 この手の終了を担保するコードは各言語でそれぞれパターンがありそうですし、別言語で実装するときには早めにおさえておきたいですね。


ここからはLTになります。が、いずれも濃い・熱い内容。

JavaのCustom Exporterを書いてみた / Writing custom exporter for Java

Alpaca Japanの@r_rudiさん(shirouさん)の発表です。Ansibleのエキスパートで、Goについても多くの知見を持っている方です。

今回はGoではなく、先程の@grimroseさんに続いてJava実装の話をしてくださいました。

普段AWSで開発していて、AWSの分散トレースサービスであるAWS X-RayのJava向けExporterがなかったので、なんと自分で実装したとのこと。 Goの実装を参考にしたそうですが、すごいですね。

X-RayとOpenCensusで用語や意味の食い違いがあって大変だったそうです。 バックエンドとOpenCensusの差異を把握し、Exporter内で調整するのだから、実装するには双方への一定の理解が求められそうです。

実装としてはExporterの抽象クラスを実装するだけで済んでしまったとのことで、200行ぐらいでできてしまったそうです。 そう聞くとExporter実装にチャレンジしたくなりますね!

TracingとLoggingの連携 / Tracing and logging correlation

Z Labの@ladicleさんの発表です。Z LabといえばKubernetesプロ集団のイメージですが、@ladicleさんもKubernetes実践入門を執筆するほどのエキスパートの方です。

トレースとロギングの連携についてデモを交えつつ話してくださいました。実は一般枠と間違ってLT枠に応募しちゃったそうです(笑)。

オブザーバビリティの三本柱としてメトリクス・トレーシング・ロギングがあり、トレースで問題点が見えてきた際、トレースから関連するログを辿れると良いとのこと。 トレースだけでは視点が足りない、というのは@sinmetalさんの発表でも指摘されていましたし、おっしゃるとおりだと思います。 そして http://peter.bourgon.org/blog/2017/02/21/metrics-tracing-and-logging.html は必読ですね!

デモはGopherに餌を上げるWebアプリケーションを作り、餌やりのエンドポイントのトレース内に与えたエサを与えたログを残すというものです。 バックエンドはJaegerです。 Gopherは魚が嫌いで、食べるのに時間がかかる作りになっています。かわいいですね。

OpenCensusのAPIにはログを埋め込めるフィールドはなく、バックエンドのJaegerがアノテーションをログに変換するため、アノテーションとして埋めていったとのことでした。 OpenTracingにはログフィールドがあるそうで、今後OpenCensusとマージされたときにどうなっていくのかは気になるところです。

Stackdiver TraceであればOpenCensus + Stackdriver Trace で分散トレース上にログを表示するで紹介されている方法もとれそうですが、ログとの連携もバックエンドとは独立したやり方にできたら嬉しいですね。

OpenCensus StatsでPaaSのメトリクスを補完する / Interpolate PaaS metrics with OpenCensus Stats

平成31年を無職で駆け抜ける予定の@apstndbさんの発表です。強いですね!

トレースの話が多くなりがちで、あまり語られないメトリクスのStatsの話をしてくださいました。

GAE/Goでは標準でざっくりしたメトリクスを取ってくれますが、アプリケーションのメトリクスは取れません。 アプリケーション固有のメトリクスを取るために、OpenCensusが使えるとのこと。

OpenCensusではochttpというHTTPハンドラーのラッパーが提供されています。 ochttpでラップされたハンドラーはラッパー内でinstrumentされるのでハンドラーの実装中に自前でOpenCensusを組み込まなくて済みます。 便利ですね。

メトリクスの内容をViewとして定義し、Exporterの設定をすれば完了です。 GAEの固有縛りとして、設定可能なMonitoredMetricsが限られたり、レポート間隔が1分以上ないといけなかったりなど注意が必要とのことでした。

Ruby実装について / About Ruby implementation

@munisystemさんと同じくWantedlyの@kawasyさんの発表です。

WantedlyではGoとRubyを主に使ってるそうですが、OpenCensusのRubyサポートは他に比べて手薄だそうです。 開発ステータスはPre-Alphaですし、Contributorも最も少なく、圧倒的に人気がないとのこと……。

そういった背景もあり、Wantedlyでは自らOpenCensusのRuby実装をやっていくそうです! フリーライドせず、積極的に貢献していく姿勢は本当にすばらしいですね!

Railsでもニーズはあるでしょうし、ぜひ盛り上がっていってほしいです。

ウェブフロントエンドからサーバーまでの一気通貫のトレーシングに挑戦してみる / Try consistent tracing from web frontend to backend servers

フューチャーアーキテクトの@shibukawaさんの発表です。GoならわかるシステムプログラミングReal World HTTPの著者でおなじみの方です。

ブラウザ上のJavaScriptからトレースを送るライブラリを作った話をしてくださいました。

ただ、悲しいことに今回作成したライブラリと同様のライブラリの存在が発表直前に発覚したとのこと(笑)。 opencensus-webがそれですが、それはそれとして自前で作ったこと自体はとてもすばらしいと思います。

ユーザーからの不具合報告に対して、一昔前はサーバーサイドのログを追えばだいたい操作内容がわかり、問題を再現できていました。 フロントエンドの操作としては単一のサーバーのエンドポイントを叩くだけ、といったシンプルな作りだったからです。

しかし近年のフロントエンドではサーバーのログだけでフロントでどういった操作をしたかを再現することはできなくなって来ました。 そういった背景もあり、フロントエンドのトレースを取りたくなったそうです。

実装としてはWebSocketでコネクションを張り、トレースを随時サーバーに送る形で実現したそうです。 フロントのSpanがサーバーのSpanとつながっている様子はちょっと感動しますね。

@shibukawaさんに言わせると、オブザーバビリティは「港区目線」すぎるとのこと。 エキスパートでない現場の人間がシステムの状況を「リアル」として把握できるようにすることが重要だそうです。

また、OpenCensus自体いろいろ足りないところが多く、「かわいい」と言っていました(笑)。 貢献する余地がいくらでもあるということなので、貢献していきたいですね!

最後に

全体を通して、非常にレベルの高い話ばかりで、勉強になりました。

各言語向けのサポート・Kubernetes・GCP・AWS・フロントエンドまで、発表内容のラインナップをみただけでも、OpenCensusの適用範囲は多岐にわたるということがわかると思います。

OpenCensusの適用範囲の広さは、OpenCensusを仕込める場所の多さです。 これは年々複雑になっていくシステムの随所にOpenCensusが入り込めるということであり、オブザーバビリティを支える重要な役割を担っていけることを意味していると思います。

現代のシステム開発を担う人間として心強いなと感じました。 ぼくも何かExporterを書いたりしてみたくなったので、そのうち何か書こうと思います。

会社ブログにイベントレポートを書くことを快く承諾してくださった主催者の@ymotongpooさん、すばらしい発表をしていただいた登壇者の皆様、会場を提供してくださったGoogle合同会社様に感謝申し上げます。

すばらしい機会を設けていただきありがとうございました!


  1. 詳細な定義については、オブザーバビリティ(可観測性)がなぜ必要だと考えるのか「オブザーバビリティ」の定義 に詳しい。 [return]
  2. Icon made by OpenCensus is licensed by Apache License 2.0
    https://github.com/census-instrumentation/opencensus-website/blob/master/LICENSE

    [return]
  3. とはいえ投げる情報として何を入れるべきかはバックエンドに応じてある程度意識する必要はありそうです。 [return]
  4. 追記(2019/04/09): 当初「他言語の実装の違い」と間違った記述していましたが、@grimroseさんからご指摘をいただき修正いたしました。ご指摘ありがとうございます。 [return]