運用とログ

アラート起因で調べるベースの運用とログの話を書いておく。

状況確認

状況確認は大事。ひとまず初動で原因が分かると嬉しいので ざっくり状況確認。

  • ログを読む
    • エラーログを読む
    • なにも出てなかったらWARNを読む
  • メトリクスを見る
    • 5xxエラーを見る
      • どのサービスがダメになってる?

状況別調査

状況別に自分が見ているところをざっくりメモベースで書いておいた。

  • 変なレスポンスが返っている
    • ログを見る
    • リクエストに紐付いた一意なIDを元にログで処理を追いかける
      • 外部通信した時はこの一意なIDと一緒にログに出力しておきたい
  • レスポンスが遅い
    • レスポンスタイムを見る
      • 特定のリクエストだけ遅い場合があるので、基本的にAverageじゃなくてPercentileを使う
      • 依存先のサービスも見る
    • サービスのCPU使用率見る
    • 特定のインスタンスのCPU使用率を見る
    • RDBやバックエンドのCPU使用率を見る
    • IOが多い可能性?ネットワーク帯域とかディスクIOを見る
    • 見れるなら、S3などの通信で使っている通信時間の合計も見る
      • S3なら、S3側に設定を追加するだけで見えるようになるはず。(ちょっと時間は掛かるけど)
    • ログを読む
    • コードを読む
  • 動作がおかしい・動かない
    • 対象のサービスのログを読む
    • 担当していないサービスでもコードを読む
    • 「アプリケーションそもそも起動してる?再起動繰り返してない?」か調べる
  • 何も分からん
    • ログとメトリクスをひたすら読む
    • SSHしてDockerコンテナのホストOSに入ってでも見る
      • サルベージ出来た情報は出来るだけ後から参照できるようにする
    • ログを送る手前で死んでる可能性があるなら、ログを送るミドルウェアのログを見る
    • ググる
      • 英語でも読む
      • GitHubのIssueとかPull Requstも探す
    • どうしても分からないなら
      • 知ってそうな仲間を頼る

まとめ

  • ひたすら読む
    • ログやメトリクスで状況確認
    • コードを読んで実装確認
    • 分かる範囲で切り分けした後、知ってそうな人に聞く
      • 知ってそうな人を頭に入れておくため、チャットなどで情報収集は欠かさない
      • ここで分からなかったことは確認して振り返って忘れずに
    • 状況から見るべきメトリクスを狭めて、メトリクスやログで原因を絞っていく
    • 変なログがあって情報量がゼロならログを見直す
      • 適切な箇所で必要なログが出るようにコードを弄る

Amazon Linux 2にBCCを入れて、Pythonのメソッド実行のトレースをしてみる

今回はBCC(BPF Compiler Collection)のツールを使って Pythonのメソッド実行のトレースをやってみます。

今回の記事の流れは以下のとおりです。

  • Amazon Linux 2を立ててBCCのインストールをする
  • 検証のためのコードを準備する
  • 実際にメソッドの呼び出しをトレースしてみる
  • まとめ

Amazon Linux 2を立ててBCCのインストールをする

Amazon Linux 2でEC2を立てます。 マネージメントコンソールから立てました。

次に、以下のコマンドでBCCを入れます。(※)

sudo amazon-linux-extras install -y BCC

簡単なインストール方法が見つかって最高って気持ちになった。感謝。

ここまでで、EC2のセットアップから、BCCのインストールまでが終わりました。

検証のためのコードを準備する

メソッドの呼び出しをトレースしたいので 以下のようなコードを用意しました。

#!/usr/bin/env python2

import time
i = 0

def log(i):
  print(i)
  time.sleep(1)

def loop(i):
  time.sleep(1)
  log(i)

while True:
  loop(i)
  i+=1

メソッドの呼び出しをトレースした際にツリー表示されるので いくつかメソッドに切り出してsleepするようにしています。

実際にメソッドの呼び出しをトレースしてみる

↑で作ったスクリプトをバックグラウンドで動かして メソッドの呼び出しをトレースしてみます。

今回は pythonflowというツールを使って トレースしてみます。

実際に動かした時のログが以下のものになります。

$ ./test.py > /dev/null &
[2] 18353
$ sudo /usr/share/bcc/tools/pythonflow 18353
Tracing method calls in python process 18353... Ctrl-C to quit.
CPU PID    TID    TIME(us) METHOD
0   18353  18353  0.271    <- ./test.py.log
0   18353  18353  0.272    <- ./test.py.loop
0   18353  18353  0.272    -> ./test.py.loop
0   18353  18353  1.273      -> ./test.py.log
0   18353  18353  2.274      <- ./test.py.log
0   18353  18353  2.274    <- ./test.py.loop
0   18353  18353  2.274    -> ./test.py.loop
0   18353  18353  3.275      -> ./test.py.log
0   18353  18353  4.276      <- ./test.py.log
0   18353  18353  4.277    <- ./test.py.loop
0   18353  18353  4.277    -> ./test.py.loop
0   18353  18353  5.277      -> ./test.py.log
0   18353  18353  6.279      <- ./test.py.log
0   18353  18353  6.279    <- ./test.py.loop
0   18353  18353  6.279    -> ./test.py.loop

なんとなく動いているのが分かります。

BCCには、いくつかのツールが入っており 今回触ったようなPythonなどの高級言語のためのツールとしては ucalls, uflow, ugc, uobjnew, ustatがあります。

今回触ったpythonflowというツールはuflowをベースにしたツールです。

上で紹介したツールの概要としては以下のとおりです。

  • ucalls: メソッドの呼び出しとシステムコールのサマリ可視化
  • uflow: メソッドフローグラフの可視化
  • ugc: GCイベントのトレース
  • ubjnew: オブジェクトの生成イベントのサマリ可視化
  • ustat: 色々なイベントの収集をして、秒間当たりのイベント数を表示してくれる

他にも色々ツールがあったり、ライブラリとして利用も出来るようです。

まとめ

今回は、Pythonの内製ツールで問題があったので、調査できるような手段を用意しておくために インストール方法の検証と動作確認を行ってみました。

今回は簡単なツールの利用に留まりましたが、障害調査などで非常に役立つと感じています。 次はJavaのトレースで試してみようかな?

今回の記事としては以上です。

AWS CDKを使ってAWS LambdaにAPI Gateway経由で呼び出す口を用意する

Lambdaを使ってAPIをホストしたい時、何使いますか? AWS CDK、おすすめです。

実際のコード

Lambda Functionを中心として、Lambda Functionに関連付けを紐付けるだけで API Gatewayなりのリソースが作成される。

#!/usr/bin/env node
import 'source-map-support/register';
import {App, Stack} from '@aws-cdk/core';
import {Runtime, Code, Function} from "@aws-cdk/aws-lambda"
import {ApiEventSource} from "@aws-cdk/aws-lambda-event-sources"

const app = new App();

const stack = new Stack(app, "example-stack")

const f = new Function(stack, "example-lambda", {
    handler: "main",
    code: Code.fromAsset("dist/"),
    runtime: Runtime.GO_1_X,
    role: role,
})

f.addEventSource(new ApiEventSource("POST", "/"))

Lambda中心でHookを追加出来るのは、Serverless FrameworkやAWS SAMと似たような形になっていて良い。 最初、AWS SAMを cdk 経由で使おうと思って調べていたら aws-sam というそのままのモジュールがあったが これは low-level constructs という感じで、CloudformationのSAMそのもの。 使おうとしても、警告出るし、使いづらかった。(Public Betaなので仕方ない気もしますが・・・) そこで、色々調べてたら @aws-cdk/aws-lambda-event-sources というパッケージがあったので 使ってみたらめっちゃ便利だったので、記事を書いた。

現状、@aws-cdk/aws-lambda-event-sources で対応しているリソースについて

現状、ApiEventSource(API Gateway)の他にも下のようなリソースと連携する事ができる。

上記リソースに関しては、ドキュメントが整備されている。 ApiEventSourceだけはドキュメントに記載がないので注意。

まとめ

AWS CDK、便利。VSCodeでTypeScript書くと、import補完もしてくれていいぞ! というわけで、AWS CDK、おすすめです。