kakakakakku blog

Weekly Tech Blog: Keep on Learning!

オブザーバビリティ(可観測性)とは何か?を学べる「Distributed Systems Observability」を読んだ

2019年頃から「オブザーバビリティ (Observability)」もしくは「可観測性」という言葉をよく聞くようになった(本記事では「オブザーバビリティ」という表記に統一する).「マイクロサービス」と同じように「バズワード」の側面があり「オブザーバビリティとは何か?」という質問に対して様々な回答が考えられると思う.

今回は「オブザーバビリティ」の理解を深めるために「Distributed Systems Observability」を読んだ.本書は O'Reilly Media で読むこともできるけど,Humio のサイトから無料でダウンロードすることもできる(メールアドレス登録は必要).著者は Cindy Sridharan となり,肩書は「Distributed Systems Engineer」と書いてあった.

www.humio.com

目次

本書には「オブザーバビリティ」をテーマに気になるトピックが並んでいて,目次を見るだけでも惹き込まれる.日本語訳はなく,個人的に載せているため,参考程度にしてもらえればと!

  1. The Need for Observability(オブザーバビリティの必要性)
  2. Monitoring and Observability(モニタリングとオブザーバビリティ)
  3. Coding and Testing for Observability(オブザーバビリティのコーディングとテスト)
  4. The Three Pillars of Observability(オブザーバビリティの3本の柱)
  5. Conclusion(結論)

1. The Need for Observability

第1章「The Need for Observability」では,「オブザーバビリティ」という用語の整理と必要性を学べる.

まず,大前提として「人によって意味は異なる」と書かれている.例えば,オブザーバビリティを「"ログ/メトリクス/トレース" のことである」と表現する人もいれば「"新しいモニタリング" のことである」と表現する人もいる. そして,本書では「システムにより良い可視性をもたらすこと (bringing better visibility into systems)」は共通していると書かれている.

さらに,以下の項目を理解して設計された「システム特性」こそが「オブザーバビリティ」であると紹介されている.分散システムは完璧に動くことはなく,予測不可能な面もある.デバッグのしやすさは堅牢なシステムをメンテナンスしたり,進化させるために必要と言える.うまく言語化されていると感じた.

  • No complex system is ever fully healthy.
  • Distributed systems are pathologically unpredictable.
  • It’s impossible to predict the myriad states of partial failure various parts of the system might end up in.
  • Failure needs to be embraced at every phase, from system design to implementation, testing, deployment, and, finally, operation.
  • Ease of debugging is a cornerstone for the maintenance and evolution of robust systems.

第1章の最後には「オブザーバビリティは運用の課題だけではない」というトピックもある.モニタリングをしたり,SRE (Site Reliability Engineering) チームが安全にデプロイをすることも重要だけど,それだけでは「オブザーバビリティは達成できない」と書いてある.

2. Monitoring and Observability

まだまだ「オブザーバビリティ」に曖昧さを感じるため,読み進めていく.第2章「Monitoring and Observability」では,オブザーバビリティとモニタリングの関係を学べる.特に最初に載っている図がわかりやすく,参考情報として日本語にした.簡単に書くと,オブザーバビリティは「モニタリングとテストのスーパーセット」であり,モニタリングとテストでは予測できなかった障害に関する情報も提供する.

f:id:kakku22:20200523100752p:plain

次に「どんなメトリクスをアラートに活用すれば良いのか?」というトピックがあり,ザッと箇条書きにすると以下のような内容が紹介されている.個人的に「RED メソッド」は知らなかった.分類はいろいろあるけど,3種類ともシステムを継続的に運用するために必要なメトリクスが揃っていると感じた.

  • SRE 本(6章)に載っている「4大シグナル」
    • レイテンシー
    • トラフィック
    • エラー
    • サチュレーション(飽和)
  • 詳解システムパフォーマンス本に載っている「USE メソッド」
    • 使用率 (Utilization)
    • 飽和 (Saturation)
    • エラー (Errors)
  • Tom Wilkie 提唱の「RED メソッド」
    • リクエストレート (Rate)
    • リクエストエラー (Error)
    • リクエスト期間 (Duration)

また,過去に流し読みをした「SRE 本」「詳解システムパフォーマンス本」に関連しているのも技術領域(トピック)の近さを感じられた.どちらも書評記事を書いてなく,もう1度読み直してまとめないと...あああ!

詳解 システム・パフォーマンス

詳解 システム・パフォーマンス

  • 作者:Brendan Gregg
  • 発売日: 2017/02/22
  • メディア: 単行本(ソフトカバー)

3. Coding and Testing for Observability

第3章「Coding and Testing for Observability」では,「オブザーバビリティ」を実現するために「どんな観点でコーディングとテストを進めれば良いのか?」を検討する指針を学べる.

障害のための「コーディング」

まず,障害を前提に,以下の項目を意識しながらコーディングをするべきと書いてある.日本語訳は参考程度に!

  • Understanding the operational semantics of the application(アプリケーションの運用上の意味を理解する)
  • Understanding the operational characteristics of the dependencies(依存関係の運用上の特性を理解する)
  • Writing code that’s debuggable(デバッグ可能なコードを書く)

1個目「アプリケーションの運用上の意味」に関しては具体例が多く載っている.特に以下の例はアプリケーションを設計する上でとても重要だと思う.DevOps な側面もあるけど,こういった非機能な側面をコーディング時にどこまで検討できるだろう.

  • How a service is deployed and with what tooling(サービスのデプロイ戦略とツール)
  • How an application handles signals(アプリケーションがシグナルをどのように処理するか)
  • How the service is drained off connections when it’s about to exit(サービスのドレイニング)
  • How graceful (or not) the restarts are(再起動がどの程度キレイに行えるか)

3個目「デバッグ可能」の指標としては「将来的に質問ができること」と書いてあり,センスのある表現だと感じた.障害時に原因を分析するだけではなく,過去に遡って傾向を調べることもあるし,今後は「質問する」という表現を使っていく.

障害のための「テスト」

最初に名言が出てくる.個人的な訳になるけど「テストはバグが存在することは示せるけど,バグが存在しないことは示せない」という表現で,これは興味深かった.とは言え,テストにより障害を防ぐことはできるため,可能な限り「本番環境を使ったテスト」も検討するべきと書いてある.

読み進めていくと,途中に「テスト戦略」をマッピングした図が載っている.画像を引用せず,簡単に紹介すると,以下の4フェーズごとにテスト戦略がまとまっている.特に「本番環境を使ったテスト」Deploy / Release / Post-release の3フェーズとなり,ここまで幅広くテストができているアプリケーションがあったら本当にスゴイと思う.

  • Pre-production
    • Unit tests など
  • Deploy
    • Load tests など
  • Release
    • Canarying や Feature flagging など
  • Post-release
    • Chaos testing や A/B tests など

また,本番環境を使ってテストをするためには,第2章で紹介したようなメトリクスを取得し,フィードバックをする仕組みも必要だと書いてある.そして,ロールバックをするなど,異常時にすぐ中止できる仕組みも必要だと書いてある.

4. The Three Pillars of Observability

第4章「The Three Pillars of Observability」では,よく「オブザーバビリティ」の紹介として聞く「ログ/メトリクス/トレース(3本の柱)」の詳細を学べる.必ずしも「3本の柱」を揃えたからと言ってオブザーバビリティを実現したことにはならないけど,より優れたアプリケーションを構築できると書いてある.冒頭には「イベントログ」の紹介もあり,表現次第では「4本の柱」にもなりそう.

なお,New Relic のレポートを読むと「イベント」まで含めた MELT (Metrics, Events, Logs, Traces) という用語を意図的に使っている.自動販売機を例にオブザーバビリティを解説されていて,とてもわかりやすく,合わせて読むと良さそう.

blog.newrelic.co.jp

「ログ」のメリットとデメリット

ログは多くのシチュエーションで使えるし,どんなパッケージにもライブラリがあり,簡単に組み込むことができるメリットがある.逆にパフォーマンスの問題があったり,重要なログをロストする可能性などはデメリットとして挙がっている.また,ログ配信を保証するための仕組みとして RELP (Reliable Event Logging Protocol) という名前が載っている.これは気になる!

en.wikipedia.org

「メトリクス」のメリットとデメリット

メトリクスは定量的な数値から構成されるため,数学的に未来予測ができる点はメリットと言える.また一定期間を過ぎたらメトリクスの解像度を下げる(ダウンサンプリング)こともできる.Prometheus の紹介も少し載っている.ただし,基本的には「ログ」「メトリクス」「単一アプリケーションスコープ」を対象にしているというデメリットもあると書いてある.

kakakakakku.hatenablog.com

「トレース」のメリットとデメリット

複数アプリケーションに対して可視性を高めるためにトレースを活用する.リクエストごとに Unique ID を伝搬しながら実現する.ミドルウェアとしては OpenTracing に準拠した ZipkinJaeger が紹介されている.とは言え,トレースする仕組みを導入したくても,既存のインフラ全てに組み込むのは難しいという課題があり,そこで「サービスメッシュ」の紹介もある.本書は2018年に出版されたこともあり,まだ IstioEnvoy という用語は載っていなかった.今後もし改訂されるなら言及されそう.

まとめ

2019年頃から「オブザーバビリティ」関連の話題をよく聞くため,理解を深めるために「Distributed Systems Observability」を読んだ.

第4章に書いてあった通り,「オブザーバビリティ」「ログ/メトリクス/トレース」情報を揃えて活用することだと理解をしていたけど,そんなに単純なものではなく,技術的にも幅広さが求められることを学べて良かった.当然ながら DevOps とも関連する側面が多く,例えば「スプリントゼロで CI/CD パイプラインを作る」というプラクティスのように「スプリントゼロでオブザーバビリティを導入する」というプラクティスまで応用できると良さそう.

www.humio.com

仮想オーディオデバイス「BlackHole」を使って Mac から音楽を配信する

「リモート会議」「リモート研修」のときに,Mac から直接音楽などを配信したかった.具体的には,リモート会議の開始前に無言で待っているのではなく,リラックスのために音楽を流したり,リモート研修の開始前にオーディオテストをするために音楽を流したりしたかった.

仮想オーディオデバイス「BlackHole」

Mac で仮想オーディオデバイス「BlackHole」を使うと簡単に実現できる.同僚に教えてもらった.

github.com

BlackHole のインストールは簡単で brew コマンドを使う.

$ brew cask install blackhole

インストールをすると,Mac のサウンドアイコンから「BlackHole 16ch」を確認できる.なお,メニューバーからサウンド設定を変更する Tips は前回の記事を見てもらえればと!

f:id:kakku22:20200511235805p:plain

kakakakakku.hatenablog.com

「BlackHole」を使う

BlackHole を使うフローを簡単に図解した.ポイントは2点ある.

  1. Mac 側は「出力装置」BlackHole を選ぶ
  2. Zoom などのビデオ配信ツール側は「入力装置(マイク)」BlackHole を選ぶ

設定をすると,例えば YouTube で流した音楽を Zoom に配信できる.

f:id:kakku22:20200512002255p:plain

まとめ

Mac で仮想オーディオデバイス「BlackHole」を使うと,Mac から直接音楽などを配信できる.便利!

便利すぎる!Mac のメニューバーでサウンド設定を変更するときは「Option キー」を使う

最近「リモート会議」「リモート研修」も多く,オーディオインタフェース(入出力)をよく切り替えている.今回は Mac で簡単にオーディオインタフェースを切り替える Tips を紹介する.なんと「Option キー」を使うだけ!

サウンドアイコンをメニューバーに追加する

まず,基本的な設定として,サウンドアイコンを Mac のメニューバーに追加する.「システム環境設定」「サウンド」と開き,1番下にある「メニューバーに音量を表示」を有効化する.

f:id:kakku22:20200508170302p:plain

すると,メニューバーにサウンドアイコンが表示される.

f:id:kakku22:20200508230934p:plain

クリックするとデフォルトは「内蔵スピーカー」しかなく,以下のような表示になる.

f:id:kakku22:20200508170314p:plain

例えば「AirPods Pro」を使って出力する場合は,以下のような表示になり,サウンドアイコンから直接「AirPods Pro」に切り替えられる.

f:id:kakku22:20200508170328p:plain

Option キー + サウンドアイコン

しかし,サウンドアイコンをクリックしても「出力装置」しか切り替えられず,マイクを使って話すなど「入力装置」を切り替える場合は,サウンドアイコンから「サウンド環境設定」をクリックして,切り替える必要がある.正直言って,面倒だった.

f:id:kakku22:20200508170338p:plain

そこで「Option キーを押しながらサウンドアイコンをクリック」すると,なんと「入力装置」も切り替えられるようになる!これは便利!以下は出力を「内蔵スピーカー」に切り替えて,入力を「Yeti」に切り替えた.

f:id:kakku22:20200508170351p:plain

まとめ

Mac で「Option キーを押しながらサウンドアイコンをクリック」すれば「出力装置」「入力装置」を簡単に切り替えられる!便利!

リモート環境 関連

デジタルホワイトボード環境を作るなら以下の記事も参考になるはず!

kakakakakku.hatenablog.com

Autify で「JS ステップ」と throw new Error() を組み合わせてアサーションを実装する

Autify のレコーディング時にシナリオに追加する「検証ステップ」は,基本的に「〜を確認する」という「正常確認」のテストになる.例えば「URL を確認する」「対象のテキストを確認する」など.しかし,実際には「特定の条件を満たさなかったらテストをエラーにする」というテストを実装したくなる場面もある.今回は Autify の「JS ステップ機能」throw new Error() を組み合わせた機能を試す.

ブログの「最終更新日」を確認して「n日」経過していたらエラーにする

「JS ステップ機能」throw new Error() を組み合わせるために,今回は題材として「ブログの最終更新日を確認するシナリオ」を作る.指定した「n日」を経過していたらエラーにするため,言い換えると「Autify を使ってアサーションを実装する」ことになる.

1.「シナリオ」を作る

シナリオ「kakakakakku blog 最終更新日 確認」を作る.基本的な操作は今までと重複するため割愛する.

2. レコーディングをする

今までと同じようにレコーディングをする.しかし今回は特にレコーディングするステップはなく,kakakakakku blog にアクセスした後に「JS ステップ機能」を使う.

  1. 「kakakakakku blog」にアクセスする
    • ✅ 最終更新日を検証する : 「n日」経過しているか?

3. JavaScript を実装する

サンプルとして,以下のような JavaScript を実装する.最終更新日を CSS Selectors から取得し,現在時刻と比較して「1日」経過していたらエラーを返す.このときに JavaScript の throw new Error() ステートメントを使うことにより,Autify 側にエラーを通知できる.昨日の記事で試した return ステートメントもそうだけど,JavaScript の基本的なステートメントと連携する Autify の仕組みはスゴイ!

var updated = new Date(document.querySelector('.entry:first-child time').attributes.datetime.value);
var now = new Date();
if ((now - updated) > (1000 * 60 * 60 * 24)) {
    throw new Error('ブログを1日以上更新していません!');
}

最終的に以下のような画面になる.

f:id:kakku22:20200507102833p:plain

4.「シナリオ」を実行する

ブログを更新した直後と1日経過後にシナリオを実行する.

⭕️ 正常終了する

f:id:kakku22:20200507102853p:plain

❌ エラーになる

f:id:kakku22:20200508095846p:plain

Autify FAQs

まとめ

Autify「JS ステップ機能」throw new Error() を組み合わせて「特定の条件を満たさなかったらテストをエラーにする」というシナリオを試した.returnthrow new Error() など,JavaScript の基本的なステートメントと連携する Autify の仕組みはスゴイ!

Autify 紹介記事

Autify で「JS ステップ」と return を組み合わせて計算結果を入力値に使う

昨日の記事では Autifiy「データ機能」を試した.テストデータのパターンを増やす場合に便利に使える.

kakakakakku.hatenablog.com

さらに E2E テストを検討していくと,「データ機能」のようにパターンを決めるのではなく「シナリオ実行時に動的に入力値を決めたい」という場面もある.例えば「現在時刻(シナリオ実行時刻)に依存したテスト」「乱数を使ったテスト」「リストからランダムに1個選んで使うテスト」など.今回は Autify の「JS ステップ機能」を使って「シナリオ実行時に計算結果を入力値に使う機能」を試す.

「JS ステップ機能」と return を組み合わせる

Autify の「JS ステップ機能」を使うと,任意の要素をクリックするなど「JavaScript コードを自由に実装できる」ことは既に試した.

kakakakakku.hatenablog.com

さらに Autify には「JavaScript で return をした計算結果を次のステップの入力値として使える」という機能がある.個人的には Autify で未サポートな挙動を実現する場合など,シナリオを細かく実装するために幅広く使える機能だと思う.

1.「シナリオ」を作る

シナリオ「kakakakakku blog 検索シナリオ(ランダム)」を作る.基本的な操作は今までと重複するため割愛する.

2. レコーディングをする

今までと同じようにレコーディングをする.今回はシンプルに以下のステップとする.

  1. 「kakakakakku blog」にアクセスする
  2. キーワード「github」で記事を検索する

f:id:kakku22:20200506152543p:plain

3. JavaScript を実装する

検索ステップの前で「JS ステップを挿入」を選ぶ.今回は以下の JavaScript コードを実装する.意味としては「プログラミング言語配列(5種類)からランダムに1個選ぶ」で,ポイントは「2行目で計算結果を return している点」となる.

var languages = ['Python', 'Go', 'Ruby', 'PHP', 'Java'];
return languages[Math.floor(Math.random() * languages.length)];

最終的に以下のような画面になる.

f:id:kakku22:20200506232041p:plain

return を実装したことにより,検索ステップの「入力値」として「他のステップから取得」を選べるようになる.計算結果(プログラミング言語名)を入力値に使えるという意味になる.最終的に以下のようなシナリオになる.

  1. 「kakakakakku blog」にアクセスする
  2. キーワード ${プログラミング言語名} で記事を検索する
    • ${プログラミング言語名}「候補リスト (Python, Go, Ruby, PHP, Java)」からランダムに選択する

f:id:kakku22:20200506153826p:plain

4.「シナリオ」を実行する

シナリオを繰り返し実行すると以下のような結果が得られる.

Java が選ばれた(Autify スクリーンショット)

f:id:kakku22:20200506155346p:plain

Ruby が選ばれた(Autify スクリーンショット)

f:id:kakku22:20200506155400p:plain

PHP が選ばれた(Autify スクリーンショット)

f:id:kakku22:20200506155538p:plain

Autify FAQs

Autify GitHub : autify-javascript-snippets

以下のリポジトリに「JS ステップ機能」に使える JavaScript サンプルが公開されている.例えば generate-random-value.js を読むと「時刻」「乱数」return する実装になっている.見てみると良いかと!

github.com

まとめ

今回は Autify を使って「シナリオ実行時に計算結果を入力値に使う機能」を試した.JavaScript で return をした計算結果を次のステップの入力値として使えるという仕組みは幅広く使えるため,Autify を使うなら覚えておくべき機能だと思う!

Autify 紹介記事