AWS 監視 運用

DatadogのCloud FunctionsでLambdaのパフォーマンスを確認するまで。X-Ray経由ですけどね。

はじめに

DatadogでLambdaを監視する方法を紹介します。
最初はインテグレーションして簡単にできると思っていましたが、思った以上に面倒でした。
DatadogはLambdaから直接、パフォーマンスなどを取得することはできません。X-Rayから間接的に取得します。
また、メトリックスはLAYERの設定を行ったり、Logに関しては新たに関数を作成して別途取得する必要があります。

今回はサンプルとしてAPI Gateway + DynamoDB + Lambda(Python)で動作する環境を監視してみたいと思います。

環境構築は下記を参考に作成してください(ありがたしクラスメソッド)。
初めてのサーバーレスアプリケーション開発 ~DynamoDBにテーブルを作成する~
初めてのサーバーレスアプリケーション開発 ~LambdaでDynamoDBの値を取得する~
初めてのサーバーレスアプリケーション開発 ~API GatewayからLambdaを呼び出す~

他の前提として
・DatadogでAWSのインテグレーション済み

X-Ray SDKをLambdaに仕込んでX-Ray、Datadogで監視する

一番手っ取り早い方法として、SDK(今回はPython)をアップロードするZIPに梱包する方法です。

開発環境、といってもAmazon Linux2を立ち上げてPython(2.7)を使える環境を整えただけです。
pipを利用するのでインストールしておきます。

wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py

まず最初に、作業用ディレクトリを作成、移動します。

mkdir workspace
cd workspace

次にX-Ray SDKを作業用ディレクトリにインストールします。

pip install aws-xray-sdk -t .

Python2.7の場合(だけ?)、X-Ray SDK以外にも依存関係がありsetuptools も必要です。

pip install setuptools -t .

X-Ray SDKを利用するには、下記の行を挿入するだけです。

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all
 
patch_all()

lambda_function.py を作業用ディレクトリに作成する。

import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

patch_all()

dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-person')

def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']

def get_persons():
    response = table.scan()
    return response['Items']

def lambda_handler(event, context):
    return get_persons() if event['person_id'] == '' else get_person(event['person_id'])

ZIPで保存。

zip -r ../upload.zip *

保存したZIPをLambdaにUploadし、保存します。
AWSで行っている場合は、一度クライアント側にSCPで持ってくるなど必要です。
RuntimeをPython2.7に変更します。

LambdaがX-Rayで見れるよう、Debugging and error handlingのactive tracingを有効にします。

API GatewayをX-Rayでトレースできるよう設定します。
Logs/Tracing からX-Ray Tracingを有効化します。
実行ロールに「AWSXrayWriteOnlyAccess」を付与。
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/enabling-x-ray.html

あとはAPI Gateway経由でアクセスしfunctionを動作させます。
その後 しばらくするとX-Rayで表示されることを確認します。

Service Map

Trace

Details

ではX-Rayで表示を確認できたためDatadog側の表示を確認します。
Cloud functionsで確認を行います。

上記の画像ではLogの収集が行われていないことが分かります。
ログの取得は下記の手順通りです。
https://docs.datadoghq.com/integrations/amazon_web_services/?tab=allpermissions#set-up-the-datadog-lambda-function

設定を行うことで、Logの取得が行われDatadog側にも反映されます。

また、メトリックスを取得したい場合は下記を参考にしLAYERを設定します。
https://docs.datadoghq.com/integrations/amazon_lambda/#custom-metrics

下記はサンプルですが、バージョンに合わせてPython36の箇所を変更します。Python27、Python37。

arn:aws:lambda:<YOUR_AWS_REGION>:464622532012:layer:Datadog-Python36-metric:1

サンプルコード

import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all
from datadog import datadog_lambda_wrapper, lambda_metric


patch_all()

dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-person')

@datadog_lambda_wrapper
def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']

def get_persons():
    response = table.scan()
    return response['Items']

def lambda_handler(event, context):
    for i in range(0, 10):
        lambda_metric("lambda_custom_metric",i, tags=['owner:kudo', 'env:demo'])

    return get_persons() if event['person_id'] == '' else get_person(event['person_id'])

以上で基本的な設定は完了です。
あとは頑張って分析してください。

あと残念ながらDatadog APMでService Mapは表示されません。

まとめ

パフォーマンスが上がらないのはインフラが悪いからと言わずにX-Rayを利用して原因(ボトルネック)を探してみましょう。APM系な話はインフラ屋だけでも出来ないし、デベロッパーだけでも出来ません。一緒になって頑張りましょう。

APMってあまり日本で使われている感じがしないのは気のせいだろうか?

-AWS, 監視, 運用
-, ,