はじめに
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で表示されることを確認します。
では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ってあまり日本で使われている感じがしないのは気のせいだろうか?