Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ぼんやりとしてたサーバレスアプリの 監視を本格的に行おうとした話

ぼんやりとしてたサーバレスアプリの 監視を本格的に行おうとした話

Koji Ishida

April 18, 2018
Tweet

More Decks by Koji Ishida

Other Decks in Technology

Transcript

  1. 自己紹介 Copyright © Acroquest Technology Co., Ltd. All rights reserved.

    2 • 石田浩司(@kojiisd) ‒ Acroquest Technology Co., Ltd. ‒ AWS系開発エンジニア/ミャンマー支社CEO ‒ 2012/10 – 2015/10 ミャンマー支社CTO ‒ 2015/10 JavaOne スピーカー ‒ 2016/11 JAWS-UG 横浜支部 ‒ 2017/06 – 2018/03 ミャンマー支社CEO/CTO ‒ 2018/03 – 本社@新横浜勤務 フロント:kintone バック :AWS の構成での開発に興味あり
  2. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 3

    サーバレスでアプリを 構築したとき 監視ってどうしてます?
  3. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 4

    最近サーバレス(AWS Lambda) で開発をする案件が増えてきまして 僕がミャンマーにいる間に
  4. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 5

    サーバレスアプリケーションの 監視について考えることも 多くなりまして 僕がミャンマーにいる間に
  5. CloudWatch 1. AWSリソースとAWSで実行しているアプリケーション をリアルタイムでモニタリング 2. CloudWatch Logs を使用して、ログファイルに対する モニタリング、保存、アクセスを、Amazon EC2

    イン スタンス、AWS CloudTrail、その他のリソースから行 う。 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 7 出展:https://aws.amazon.com/jp/documentation/cloudwatch/ 今回はログ監視で実現したい
  6. CloudWatch 1. AWSリソースとAWSで実行しているアプリケーション をリアルタイムでモニタリング 2. CloudWatch Logs を使用して、ログファイルに対する モニタリング、保存、アクセスを、Amazon EC2

    イン スタンス、AWS CloudTrail、その他のリソースから行 う。 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 8 出展:https://aws.amazon.com/jp/documentation/cloudwatch/ 一見するととてもよさそう
  7. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 10

    実際に適用を 考えてみたら・・・
  8. かゆいところに手が届かない感じ 1. 予期せぬエラーログが出ているかどうか、定期的にメー ル通知したい。(割と緩い監視) 2. 指定するエラーログは正規表現で書きたい。 3. 複数のロググループをまとめて1つの設定で監視したい。 4. メール通知には、エラーログの内容を含めたい。

    5. お金かけたくない(組み合わせで料金かかるイメージ)。 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 11 CloudWatchのメトリクスフィルタ・サブスクリプションで 実現しようとするも・・・
  9. かゆいところに手が届かない感じ 1. 予期せぬエラーログが出ているかどうか、定期的にメー ル通知したい。(割と緩い監視) 2. 指定するエラーログは正規表現で書きたい。 3. 複数のロググループをまとめて1つの設定で監視したい。 4. メール通知には、エラーログの内容を含めたい。

    5. お金かけたくない(組み合わせで料金かかるイメージ)。 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 12 メトリクスフィルタの場合 1. 通知するエラーログを正規表現で指定できない。 2. 各ロググループ単位でしかエラー通知の設定ができない。 3. エラーログの内容をメールの文面に含められない。 ?
  10. かゆいところに手が届かない感じ 1. 予期せぬエラーログが出ているかどうか、定期的にメー ル通知したい。(割と緩い監視) 2. 指定するエラーログは正規表現で書きたい。 3. 複数のロググループをまとめて1つの設定で監視したい。 4. メール通知には、エラーログの内容を含めたい。

    5. お金かけたくない(組み合わせで料金かかるイメージ)。 Copyright © Acroquest Technology Co., Ltd. All rights reserved. 13 CloudWatch Logs サブスクリプションの場合 1. 通知するエラーログを正規表現で指定するために、ログ出力ごとに 通知を処理する必要がある。(手間) 2. 各ロググループ単位でしかエラー通知の設定ができない。 ?
  11. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 14

    そもそも今後も末永く適用する 予定なので、安易にお金払って AWSのサービスというのも いかがなものか ※あくまで個人の見解です
  12. 仕様の整理(動作イメージ) こんな感じの動作にしました。 Copyright © Acroquest Technology Co., Ltd. All rights

    reserved. 17 1. Cronから呼び出されたParent Lambdaが、S3から前回実行時刻 を取得する。 2. Parent Lambdaが指定した prefixごとに子Lambdaを呼びだ す。 3. 呼び出された子Lambdaが指 定prefixグループのログを収集し、 前回実行時刻以降のログに絞り込 む。 4. ログ内容を整形し、SNSへ通知。
  13. 各種呼び出しはPythonでサクッと実装 Copyright © Acroquest Technology Co., Ltd. All rights reserved.

    18 // S3バケット読み込み s3 = boto3.session.Session().resource('s3') bucket_name = os.environ['ALERT_LOG_BUCKET'] bucket = s3.Bucket(bucket_name) key = os.environ['ALERT_LOG_KEY'] object = bucket.Object(key) last_updated_time_str = object.get()['Body'].read().decode('utf-8') result = int(last_updated_time_str) ... // S3バケット書き込み object = bucket.Object(key) object.put( Body=str(last_exec_time).encode('utf-8'), ContentEncoding='utf-8', ContentType='text/plain‘ ) S3呼び出し function_name = os.environ['FILTERED_ALERT_LOGS'] lambda_client = boto3.session.Session().client('lambda') lambda_client.invoke( FunctionName=function_name, InvocationType='Event', LogType='Tail', Payload=json.dumps(request) ) Lambda呼び出し // ロググループの取得 client = boto3.session.Session().client('logs') response = client.describe_log_groups( logGroupNamePrefix=prefix ) ... // ログストリームの取得 response = client.describe_log_streams( logGroupName=group_name, orderBy='LastEventTime', descending=True, limit=limit ) ... // ログイベントの取得 logs = client.get_log_events( logGroupName=group_name, logStreamName=stream_name, startTime=start_time, endTime=end_time, startFromHead=True ) CloudWatch呼び出し message = '整形したCloudWatchログ‘ topic_arn = os.environ['ALERT_LOG_TOPIC_ARN'] subject = os.environ['ALERT_LOG_SUBJECT'] sns_request_params = { 'TopicArn': topic_arn, 'Message': message, 'Subject': subject } sns_client = boto3.session.Session().client('sns') sns_client.publish(**sns_request_params) SNS呼び出し
  14. 結果・・・ Copyright © Acroquest Technology Co., Ltd. All rights reserved.

    19 1. 予期せぬエラーログが出ているかどうか、定期的にメール通知 したい。(割と緩い監視) OK 2. 指定するエラーログは正規表現で書きたい。 OK 3. 複数のロググループをまとめて1つの設定で監視したい。 OK 4. メール通知には、エラーログの内容を含めたい。 OK 5. お金かけたくない(組み合わせで料金かかるイメージ)。 たぶんOK https://github.com/acroquest/aws-cloudwatch-logwatcher/
  15. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 21

    DynamoDBの監視もしたい。 キャパシティユニットの消費量を 割合で監視するイメージで。 JAWS-UGで話すならネタあげるよ(^^ by とても部下想いな上司
  16. キャパシティユニットとは 1. DynamoDBテーブルのスループット設定。読み込みと 書き込みの性能を事前に定義し、テーブルのパフォーマ ンスを確保する。 Copyright © Acroquest Technology Co.,

    Ltd. All rights reserved. 22 詳細は公式ページで https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/HowItWorks.ProvisionedThroughput.html
  17. CloudWatchメトリクスでは使用量のみ取得可能 1. CloudWatchメトリクスでキャパティティユニットの監 視は可能だが、取得できるのは使用「量」のみ。 ① ConsumedReadCapacityUnits / ConsumedWriteCapacityUnits Copyright ©

    Acroquest Technology Co., Ltd. All rights reserved. 23 事前に定義したキャパシティユニット (ProvisionedRead/WriteCapacityUnits) を踏まえた割合計算には実装が必要
  18. 仕様の整理(動作イメージ) こんな感じの動作を作る。 Copyright © Acroquest Technology Co., Ltd. All rights

    reserved. 25 ① CloudWatchが定期的に DynamoDBの消費キャパシティを 記録してくれる。 ② 定期実行でLambdaスクリプト が開始し、DynamoDBに設定され ている最新のキャパシティユニット 設定値を取得する。 ③ 過去1時間分のメトリクスを、5 分間隔でキャパシティユニット平均 使用量を取得する。 ④ 設定値と実際の値からユニット 使用割合を計算する。 ①メトリクス記録 (自動) ③メトリクス取得 (定期実行) ②設定値取得 (定期実行) ④割合計算
  19. 実装しました メトリクスはこんな実装で取得できる。 Copyright © Acroquest Technology Co., Ltd. All rights

    reserved. 26 cloud_watch.get_metric_statistics( Namespace=parameters['namespace'], MetricName=parameters['metric_name'], Dimensions=[ { 'Name': parameters['dimension_name'], 'Value': parameters['dimension_value'] } ], StartTime=parameters['start_time'], EndTime=parameters['end_time'], Period=parameters['period'], Statistics=parameters['statistics'], Unit=parameters['unit']) Key Value Namespace AWS/DynamoDB MetricName ConsumedReadCapacity Dimensions.Name TableName Dimensions.Value [DynamoDBテーブル名] StartTime 開始時刻 EndTime 終了時刻(現在時刻) Period 期間(秒) Statistics [‘Average’] Unit Count 例:読み込みキャパシティ使用量取得
  20. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 27

    https://camo.qiitausercontent.com/9c7fe153a3ed69ed92643cb5b1fb8b 70c5911145/68747470733a2f2f71696974612d696d6167652d73746f72 652e73332e616d617a6f6e6177732e636f6d2f302f3133333833382f303 93265656430612d373466332d663762662d373637362d366436623263 6537616537322e706e67 詳しくは で https://qiita.com/kojiisd/items/c7f0fe22e1353eecb909
  21. 会社のツールにも組み込んだよ!(今日) Copyright © Acroquest Technology Co., Ltd. All rights reserved.

    28 だれかテストして! 割合計算&設定回数の 閾値超えでメール送付、という処理を追加。
  22. まとめ 1. AWS Lambdaで開発したアプリケーションの監視を CloudWatch Logsからログ収集して実施するスクリプ トを開発しました。 2. DynamoDBのキャパシティユニット消費量を、使用量 ではなく割合で監視できるスクリプトを開発しました。

    3. 各AWSサービスのできること/できないことを理解し て適用を考えることが重要 4. 誰かさっきのスクリプトテストして! Copyright © Acroquest Technology Co., Ltd. All rights reserved. 30
  23. まとめ 1. AWS Lambdaで開発したアプリケーションの監視を CloudWatch Logsからログ収集して実施するスクリプ トを開発しました。 2. DynamoDBのキャパシティユニット消費量を、使用量 ではなく割合で監視できるスクリプトを開発しました。

    3. 各AWSサービスのできること/できないことを理解し て適用を考えることが重要 4. サーバレスの監視って、いろいろな人と話をしたい 5. 誰かさっきのスクリプトテストして! Copyright © Acroquest Technology Co., Ltd. All rights reserved. 31
  24. Copyright © Acroquest Technology Co., Ltd. All rights reserved. 32

    Infrastructures Evolution ご清聴ありがとうございました