「入門 監視」を読んだので要約する

## 概要

システムのどの部分をどのように監視すべきか、また監視をどのように改善していくべきかについて解説する書籍です。
https://www.oreilly.co.jp/books/9784873118642/


## はじめに
監視を以下のように定義します。
「監視とは、あるシステムやそのシステムのコンポーネントの振る舞いや出力を観察しチェックし続ける行為である。」

## 第1部 監視の原則

### 1章 監視のアンチパターン

* ツールに依存しない。依存しても監視の仕組みは良くならない。
  * 観察者効果(監視行為が監視体調を変化させてしまうこと)は無視して良い。現代では、監視ツールがシステムに加える負荷は大したことではない。
  * ツールの数については「仕事ができる最低限の数」にするのが適切。ツールが別の情報を提供するのであれば多くても問題はない。
  * ダッシュボードで「一目で分かる」は迷信。ダッシュボードに情報を詰め込みすぎると効率を損ねる。
* 監視は全員がやるべき仕事であり、チームや部署内での役割ではない。
  * 全員が本番環境全体に責任を持つことが重要。
* チェックボックス監視
  * 外部からの指示で監視することを求められてとりあえず設定する監視。うるさく、信頼できず、監視前よりもひどくなる。
  * システムが「動いてる」ことを監視するのであれば、個別のアラートは意味がないかもしれない。
* 監視を支えにしない
  * 監視を杖のように扱ってはならない。脆く壊れやすいシステムは監視をするだけではシステムが直るわけではないので、状況改善には繋がらない。

### 2章 監視のデザインパターン

* 組み合わせ可能な監視を使う
  * 専門化されたコンポーネントを疏結合で組み合わせて監視プラットフォームを作る。
* 監視のコンポーネントは以下の通り。
    * データ収集
      * 手法としてプル型とプッシュ型がある。プッシュ型はポーリングの必要がなく、高可用性である。
      * メトリクスにはカウンタ型(車で言う走行距離)とゲージ型(車で言う速度計)がある。
      * ログは構造化ログ(JSON)が良い。
    * データストレージ
      * 時系列に応じてロールアップさせたり、Elasticserchなど検索可能なロギングプラットフォームを使うのが良い。
    * 可視化
      * 円グラフには過程やトレンドといった変化の情報を含めないので、棒グラフで可視化する方が良い。
    * 分析とレポート
      * 分析結果を基にSLAを定義することが可能。ただ、NWやクラウド基盤以上の可用性は提供することが出来ない。
    * アラート
      *  アラートを出すことが目的なのではなく、結果の一つの形でしかない。
* ユーザ視点での監視から手掛ける
  * HTTPのレスポンスコードやリクエスト時間など、ユーザから近く影響が大きい部分から監視を行う。
* 作るのではなく買う
  * 既存の監視ツールは、自前で作るよりも安く、専門家による高レベルな監視を手軽に使える。よって、プロダクト自体の改善にフォーカス出来る。

### 3章 アラート、オンコール、インシデント管理

* 良いアラートの仕組みを作る
  * アラートにメールを使わない。
    * アラート疲れの原因になる。急ぎのアラートはSMSやPagerDutyなどのページャに、それ以外はチャットルームに送るべき。
  * 手順書を用意する。
    * アラート自身に、アラートの内容(サービス内容、責任者、インフラの構成や依存関係)や修復の手順が分かるリンクを入れる。ただ、対応がコピペで済むくらいのコマンドであれば、修復自体を自動化してアラートを無くすべき。
  * 固定の閾値に囚われない。
    * 「ディスクの使用量80％でアラート」という内容だと、短期間で使用量が急上昇するような変化量やグラフの傾きに対して検知できない。移動平均(moving average)や信頼区間(confidence band)などの統計情報を適用することでより意味のあるアラートに出来る。
  * まずは自動復旧を目指す
    * 単純な再起動で解消できるのであれば自動化する。アラート疲れを解消するには最も効果的。
* オンコール
  * 何か問題が起きた時に対応できるようにしておく担当のこと。
  * 常に同じ人が担当する事のないように、上手にオンコールローテーションを組む。世界各地に社員がいるサービスであれば、タイムゾーンごとに担当を交代するFollow-the-sunローテーションがにすると夜中担当が減るため、お勧め。
  * ソフトウェアエンジニアもローテーションに入れることがお勧め。オンコール中の問題に対応することによって当事者感を持ち、アラートをすくなくするためのインセンティブに繋がる。
* インシデント管理
  * ITILのフレームワークをサービスに合わせてに加工して使うのがお勧め。サービス停止が数分以上になるようなインシデント対応には、役割割りをきちんとするのが重要。特に「コミュニケーション調査役(communication liaison)」を起き、経営者とインシデント解決に取り組む担当者の間に立って、経営者が担当者の邪魔しないようにする必要がある。

### 4章 統計入門

* より良いアラートを出すために、データに対して統計的なアプローチをすると効果的。
* 移動平均(moving average)
  * 時系列データは「最近取得したデータポイントで平均を計算」することで直近の変化を計測できる。デメリットとして、一時的にスパイクした値を平準化するため正確性を損ねることがある。
* 中央値(median)
  * 平均が対象を正確に表さない時に効果的。データセットの真ん中の値を表す。一方向に大きな偏りのあるデータを扱う場合は中央値の方がデータの特性を適切に表すことがある。
* 周期性(seasonality)
  * 時系列データのパターンについて表現する方法。

## 第2部　監視戦略

### 5章 ビジネスを監視する

* ビジネスKPI
  * 経営者の気にするKPIに回答出来るメトリクスを把握する。以下は一例。
     * 月次経営収益(monthly recurring revenue)
     * 顧客当たりの収益(revenue per customer)
     * 課金顧客の数(number of paying customers)
* ビジネスKPIを技術指標に紐づける
  * 自動車メーカーは速度を計測できない車を作らない。監視に必要な計測データはあらかじめデザイン段階で組み込んでおく必要がある。
  * 何を計測するべきか、プロダクトマネージャと相談して決める。

### 6章 フロントエンド監視

* ブラウザやネイティブアプリによって実行される全てをフロントエンドと定義する。
* フロントエンドにおける監視のゴールは「動き続ける」ではなく「素早くロードされる」である。
  * ページロードが1秒遅くなると、平均でページビューが11%、コンバージョンが7%、顧客満足度が16%下がると言われる。
* リアルユーザ監視(RUM)とシンセティック監視(synthetic monitoring)の2つのアプローチがある。
  * Google AnalyticsはRUMの一種である。監視のデータとして実際のユーザトラフィックを使い、各ページに埋め込んだJavaScriptのスニペットから監視ツールにメトリクスを送信する。
  * WebPageTest.orgのようなツールはシンセティック監視を行う。偽のリクエストを生成して監視データを取得する。
* Navigation Timing APIを使う
  * ブラウザはNavigation Timing APIを通じてページパフォーマンスのメトリクスを提供している。パフォーマンスのトラブルシューティングに有効なのは以下のメトリクス。これらのメトリクスを四則計算し、必要な監視を行う。
     * NavigationStart
          * ブラウザによってページリクエストが開始されたタイミング
     * domLoading
          * DOMがコンパイルされロードが始まったタイミング
     * dominteractive
          * ページが使用可能になったと考えられるタイミング
     * domContentLoaded
          * すべてのスクリプトが実行されたタイミング
     * domComplete
          * ページがすべて(HTML,CSS,JavaScript)のロードを終えたタイミング
* WebPageTest.orgを使う
  * プルリクエストごとにフロントエンドへのパフォーマンス影響を計測する、といったテストに使える。

### 7章 アプリケーション監視

* データベースクエリの実行にかかった時間、APIが応答するのにかかった時間など、メトリクスでアプリケーションを計測する。
* StatsDは、コードの中にメトリクスを追加するためのツール。
  * UDP経由でメトリクスをStatsDサーバへ送信する。
  * ログイン失敗回数や処理時間の計測が可能。
* /healthエンドポイント監視
  * HTTPエンドポイントの健全性を監視する。結果をJSONで返すように作る。
* アプリケーションログ監視
  * 形式をメトリクスにするべきか、ログにするべきかは検討する。メトリクスの方がメタデータを保持しやすいが、ケースによって効果は変わる。
* マイクロサービス監視
  * 分散トレーシングというマイクロサービス特有の複雑なサービス間のやり取りを監視するための方法論。システムに入ってくるリクエストに一意なリクエストIDをタグ付けし、リクエストがどのサービスにアクセスし、どのくらいの時間を過ごしたかを計測する。

### 8章 サーバ監視

* OSの標準的なメトリクスを監視する。サーバレスアーキテクチャでも、そのプラットフォームを提供するためのサーバは存在している。
* CPU、メモリ、ネットワーク、ディスク、ロードアベレージ、SSL証明書は監視する。
* SNMPをサーバ監視に使うのは非推奨。データを平文で送るのでセキュリティ的に問題あり。プッシュベースでより良いツールがあるのでそちらを使う。
* Webサーバ
  * 秒間リクエスト数とHTTPのステータスコード監視を行う。
* データベースサーバ
  * データベースサーバにどの程度負荷がかかっているか計測するために、コネクション数とスロークエリを監視する。
* メッセージキュー
  * キューが溜まっていないか計測するために、キューの長さと消費率を監視する。
* キャッシュ
  * キャッシュから追い出されたアイテム数(evicted items)キャッシュヒット率(cache-hit-ratio)を計測する。キャッシュヒットについては100%を求めない。
* ログ
  * 取得したログはログ解析ツールで分析できるようにする。

### 9章 ネットワーク監視

* 音声と映像
  * よりユーザ視点での監視ということで、レイテンシ、ジッダ、パケットロスの項目を計測する。これらストリーム品質のためにQoSを設定することもあり。

### 10章 セキュリティ監視

* 脅威とリスクを見積もり、不正アクセス時に適切な決断を下すための監視。
* ユーザ、コマンド、ファイルシステムへの監査
    * auditdをセットアップする。syslogが動いていないときでも動作し続けられるようにセキュリティ用に用意されたLinuxのユーザベースのインターフェース。以下のログを取得することによりコンプライアンス実現が可能。
      * 全てのsudoの実行、コマンドの実行、実行者。
      * ファイルアクセスと、ファイルの変更内容、時刻、変更者。
      * ユーザ認証の試行と失敗。
* ホスト型侵入検知システム(HIDS)
 * rkhunterはルートキットの検知に効果的。
* ネットワーク侵入検知システム(NIDS)
 * ファイアウォールで不足するネットワークに関する情報をNIDSにて取得する。