2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【AWS】CloudWatchはどこまで自動でログを取ってくれるのか、境界線を1枚の図に整理してみた

2
Posted at

はじめに

EC2を立てて、いざ監視を設定しようとCloudWatchを開いたとき、「CPU使用率はあるのに、メモリ使用率がどこにもない」と探し回ったことはありませんか?

これは仕組み上そうなる明確な理由があります。
この記事では「CloudWatchはどこまで自動で取ってくれて、どこから先は自分で用意するのか」の境界線を1枚の図に整理します。この境界線が頭に入ると、監視の設計は「この情報はどの層にあるか」を判定するだけの作業に変わります。

対象読者:AWSを触り始めて、監視まわりで「何が自動で溜まっていて、何を自分で作る必要があるのか」がまだ曖昧な人

参考文献

この記事は以下の公式ドキュメントをもとに書いています。まず一次情報に当たりたい人はこちらへ。

結論——境界線は「AWSの立場から見えるか」

先に結論の図を貼ります。

cloudwatch-visibility-layers.png

何が自動で取れるかは、サービスごとの気分で決まっているわけではありません。責任共有モデル——「ここから下はAWSが管理し、ここから上は利用者が管理する」という区分け——の観測版として決まっています。

AWSが自分の立場から観測できる層は、自動で溜まっているか、少なくとも有効化ひとつで取れる。AWSから見えない層は、自分で観測点を作るしかない。判断基準はこれだけなんです。

何もしなくても既に溜まっているもの

アカウントを作った瞬間から、次の3つは追加設定なしで記録され続けています。

何が 中身 保持期間 追加設定
CloudWatch Metrics AWSサービスが発行する数値。CPU使用率、Lambda実行回数など 15ヶ月。古いデータほど粗くなる 不要
CloudTrail Event history 管理イベントの操作履歴。誰が・いつ・何をしたか 90日 不要
AWS Health Dashboard AWS側の障害・メンテナンス情報。該当イベント発生時に表示 イベントログは過去90日 不要

見落としがちな点を2つ補足します。

まず、Metricsの「15ヶ月保持」は「15ヶ月ずっと細かく見られる」という意味ではありません。1分粒度のデータは15日、5分粒度は63日、1時間粒度が455日(約15ヶ月)という段階式で、古いデータは自動的に集約されて粗くなります。「先月の障害を1分粒度で振り返りたい」と思ったときには、その粒度のデータはもう存在しない——調査してから知ると地味に痛い仕様です。

もうひとつ、CloudTrailのEvent historyに載るのは管理イベント(リソースの作成・変更・削除といった操作)だけです。S3のオブジェクト取得のようなデータイベントは含まれませんし、90日を過ぎた履歴は遡れません。それより長く・広く残したければ、証跡(Trail)やCloudTrail Lakeを自分で作ることになります。

この記事では料金の具体値には触れません。無料利用枠や課金条件は変わりやすく、書いた瞬間から古くなるためです。最新はAWS公式の料金ページで確認してください。

なぜ③ OSの中身は自動で取れないのか

冒頭の「メモリ使用率がない」問題の答えがここです。

EC2のCPU使用率は、ハイパーバイザ1——つまり仮想マシンの外側——から測定できます。「このVMにCPU時間をどれだけ割り当てたか」はAWS側の帳簿に載っている情報だからです。ネットワークの転送量やディスクI/Oの回数も同じ理屈で外から数えられます2

一方、メモリ使用率はゲストOSの内部情報です。ハイパーバイザから見えるのは「このVMにメモリを何GB割り当てたか」までで、その中でどのプロセスがどれだけ使い、どれだけがキャッシュとして確保されているかは、OSの中に入らないと分かりません。ディスクの空き容量も同様で、ファイルシステムを理解しているのはOSだけです。

だからAWSは「中に観測点を置いてください」という設計にしています。それがCloudWatch Agentです。インスタンスにインストールして設定を書くと、メモリやディスク使用率をカスタムメトリクスとして送ってくれます。

cloudwatch-agent-config.json
{
  "metrics": {
    "metrics_collected": {
      "mem": {
        "measurement": ["mem_used_percent"]
      },
      "disk": {
        "measurement": ["used_percent"],
        "resources": ["/"]
      }
    }
  }
}

これはAWSの手抜きではなく、仮想化の構造上の制約です。実際、他のクラウドでもゲストOS内部のメトリクスにはエージェントを要求する構造は同じです。

なぜ④ アプリのロジックは取れないのか

同じ理屈をもう1段上に適用すると、④も説明できます。AWSはあなたのコードの中で何が起きたかを知る立場にありません。

「注文処理が在庫不足で失敗した」「この例外はどのリクエストで起きた」「処理AとBは同じユーザーの一連の操作だ」——こうした情報は、コードがログとして吐き出さない限り、この世のどこにも存在しません。存在しないものは、どんな監視サービスを持ってきても収集できないのです。

なのでこの層は、アプリケーションログを自分で設計して吐く、が答えになります。EC2ならログをファイルに書き出しておき、CloudWatch Agentのlogs設定でそのファイルを収集してCloudWatch Logsへ送るのが定番です(Agentはプロセスのstdoutを直接拾うわけではなく、設定で指定したファイルを収集します)。構造化ログにする、相関IDを載せる、例外はスタックトレース付きで記録する、といった話はすべてこの層の設計論です。

ただしLambdaは例外——境界線の正体は「管理責任の位置」

ここで面白い例外がひとつあります。Lambdaです。私はこの例外こそが、境界線の正体を一番よく説明してくれると思っています。

Lambdaの関数コードがstdoutに書いた内容は、実行ロールにログ書き込み権限が付いていれば(コンソールから関数を作ると通常は自動で付与されます)、コードを1行も足さずにCloudWatch Logsの /aws/lambda/関数名 というロググループに入ります。④のアプリ層のログなのに、実質自動なんです。さっきの理屈と矛盾していないでしょうか?

cloudwatch-lambda-vs-ec2.png

矛盾していません。Lambdaでは、コードを実行するランタイムや実行環境をAWSが管理しているからです。stdoutの受け口がAWSの管理領域の中にあるので、AWSの立場から見える。だから自動で取れる。

つまり境界線は「層の高さ」で固定されているのではなく、「管理責任がどこで切れるか」でサービスごとに動きます。EC2はOSから上があなたの責任なので、境界線が低い位置にある。Lambdaはランタイムから下をAWSが管理しているので、境界線がぐっと高い位置にある(もちろんLambdaでも、コード本体・依存ライブラリ・IAM設定はあなたの責任のままです)。責任共有モデルの観測版、という整理はこういう意味です。

Lambdaでも、実行ロールにCloudWatch Logsへの書き込み権限(AWSLambdaBasicExecutionRoleなどが付与する logs:CreateLogGroup / logs:CreateLogStream / logs:PutLogEvents)は必要です。「Lambdaのログが出ない」と悩んだら、コードより先に実行ロールを疑ってください。

層別の早見表

ここまでを1枚の表にまとめます。

AWSから見えるか 取るための手段
④ アプリのロジック ビジネス処理・例外・相関ID 見えない コードでログを吐く。Lambdaのようにランタイムまで管理を委ねた形態では自動
③ OSの中身 メモリ・ディスク使用率・プロセス 見えない CloudWatch Agentを入れる
② AWSサービスの動作 Lambda実行回数・RDS接続数 見える 自動。CloudWatch Metrics
① ハイパーバイザから見える数値 CPU・ネットワーク・ディスクI/O 見える 自動。CloudWatch Metrics
⓪ API呼び出しの履歴 誰が・いつ・何を操作したか 見える 自動。CloudTrail Event history

②で自動なのはメトリクス(数値)です。VPC Flow LogsやELBのアクセスログのような「AWSサービスが出すログ」は、AWSの管理領域内の情報ですが、有効化の設定をしないと記録されません。「自動」と「設定一発で取れる」の間にもう1つ層があるイメージで、ここは別の記事で扱う予定です。

ありがちなつまずき

この境界線を知らないまま監視に取り組むと、だいたい同じ場所でつまずきます。心当たりがないか確認してみてください。

  • メモリ使用率をCloudWatchのメトリクス一覧で延々と探す。構造上そこには存在しないので、探すのではなくAgentを入れるのが正解です
  • Lambdaのログが出ず、コードのログ出力処理を疑って書き換え続ける。原因は実行ロールの権限不足であることが多いです
  • 障害調査で91日前の操作履歴が必要になり、Event historyを遡れないことをその日に知る。長期保存の証跡は「必要になってから」では作れません
  • CloudWatch Logsのロググループの保持期間がデフォルトで「失効しない」設定であることに気づかず、ログが無限に溜まり続ける。ロググループを作ったら保持期間を決める癖をつけると安全です

まとめ

監視の設計で迷ったら、問いはひとつだけです。「その情報は、AWSの立場から見えるか?」

見えるなら、既に溜まっているか、有効化ひとつで取れます。やることは探し方と有効化の場所を覚えることだけ。見えないなら、観測点を自分で作ります。OSの中ならエージェント、コードの中なら自分でログを吐く。そしてLambdaの例外が教えてくれるとおり、この境界線は管理責任をAWSにどれだけ委ねるかで動きます。

私はこの整理に行き着いてから、「どの監視ツールを使えばいいのか」という問いが「この情報はどの層にあるか」という問いに置き換わり、監視設計で迷う時間がかなり減りました。もし「これはどっちの層に落ちるのか」と判断に迷う情報があれば、コメントで教えてください。次は「自動ではないが設定一発で取れる層」——VPC Flow LogsやELBアクセスログのような有効化待ちのログたち——を整理する予定です。

  1. 1台の物理マシンの上で複数の仮想マシンを動かすための仮想化ソフトウェア。通常の仮想化EC2インスタンスはこの上で動いている(ハイパーバイザを介さないベアメタルインスタンスという例外もある)。

  2. 厳密には、EC2標準メトリクスのディスクI/O(DiskReadOpsなど)が対象とするのはインスタンスストアで、EBSボリュームのI/OはAWS/EBSという別の名前空間のメトリクスとして記録される。どちらも「外から数えられる」層である点は同じ。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?