はじめに
2020年10月にプレビューとなった AWS Lambda Extensions により,コード変更なしに Lambda 関数の AppDynamics での監視が可能となりました。
AWS Lambda Extensions(プレビュー)を構築する
これまでは,AppDynamics Tracer SDK を用いるため Lambda 関数のコード変更が必要でしたが, AppDynamics Extension Layer を追加することによりコード変更なしでモニタリング可能となりました。
本記事では,AWS SAM CLI を用いて Lambda 関数のテスト/デプロイ, AppDynamics による性能監視を試してみます。
AppDynamics Lambda Extension 利用前提条件
- Node.js 10+, Python 3.6+ で書かれた Lambda 関数がインストゥルメント可能
- Serverless APM for AWS Lambda subscription へサブスクライブ済み
- AppDynamics SaaS Controller : バージョン 4.5.11 以降が利用可能
利用可能な AWS リージョン
2020年12月時点では,以下のAWSリージョンで Lambda Extension 経由での性能監視が可能です。
- ap-northeast-1 (東京)
- ap-northeast-2 (ソウル)
- ap-south-1
- ap-southeast-1
- ap-southeast-2
- eu-central-1
- eu-north-1
- eu-west-1
- eu-west-2
- eu-west-3
- ca-central-1
- sa-east-1
- us-east-1
- us-east-2
- us-west-1
インストゥルメント手順公式ドキュメント
2020年12月時点で英語版のみとなりますが,Extension を用いた Lambda 関数のインストゥルメント手順の公式ドキュメントはこちらになります。
以下にインストゥルメント手順を解説いたします。
Serverless APM for AWS Lambda subscription へサブスクライブ
以下の手順で Serverless APM for AWS Lambda subscription のサブスクライブを行います。
- Serverless APM for AWS Lambda subscription から Continue to Subscribe をクリック
- Subscribe をクリック
- Set Up Your Account をクリック
- AppDynamics SaaS コントローラURL/コントローラアクセスキーを入力
サブスクリプションの確認は AWS Marketplace > Manage subscriptions から行うことができます。
AWS SAM CLI による Lambda 関数のデプロイと AppDynamics Extension インストゥルメント
今回は AWS マネジメントコンソールを極力用いず,AWS SAM CLI を用いて監視対象の Lambda 関数のデプロイを行ってみます。AWS SAM CLI のインストールをされていない方は以下のリンクからご自分の利用環境に合わせてインストールを事前に行ってください。
template.yaml の編集
SAM のテンプレートを編集し,Layers に 以下のように ARN,
arn:aws:lambda:ap-northeast-1:716333212585:layer:appdynamics-lambda-extension:9 を設定します(東京リージョンの場合)。利用リージョンが異なる場合は ap-northeast-1 を適宜変更してください。
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: AppDynamics Lambda extension Resources: Function: Type: 'AWS::Serverless::Function' Properties: Handler: lambda_function.lambda_handler Runtime: python3.8 CodeUri: code Handler: app.lambda_handler MemorySize: 128 Timeout: 3 Environment: Variables: APPDYNAMICS_CONTROLLER_HOST: your-account.saas.appdynamics.com APPDYNAMICS_SERVERLESS_API_ENDPOINT: 'https://syd-sls-agent-api.saas.appdynamics.com' APPDYNAMICS_ACCOUNT_NAME: your-account APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY: your-access-key APPDYNAMICS_APPLICATION_NAME: your-application APPDYNAMICS_TIER_NAME: your-tier AWS_LAMBDA_EXEC_WRAPPER: /opt/appdynamics-extension-script Layers: - >- arn:aws:lambda:ap-northeast-1:716333212585:layer:appdynamics-lambda-extension:9
各環境変数はご利用の AppDynamics コントローラへのアクセス情報,アプリケーション名,Tier名に適宜置き換えてください。なお,アクセスキーは SaaS コントローラ の右上の歯車アイコン – License – Account で確認することができます。
サンプル Python コード
今回は以下の非常にシンプルなサンプルコードを用います。ifconfig.io に GET リクエストを送り,グローバル IP アドレスを取得します。
import urllib.request def lambda_handler(event, context): url = 'https://ifconfig.io/' req = urllib.request.Request(url) req.add_header("User-Agent", 'curl') with urllib.request.urlopen(req) as res: body = res.read() return { 'statusCode': 200, 'body': body.decode().strip() }
このスクリプトは code/app.py として保存しておきます。
ビルド
今回は Python 3.8 Runtime を用いますが,ローカル環境で 正常に SAM から Python 3.8 を実行できない場合は(Python 2.7 との競合等),sam build -u でDocker コンテナを利用することにより抽象化/仮想化することができます。
$ sam build -u Starting Build inside a container Building codeuri: code runtime: python3.8 metadata: {} functions: ['SampleFunction'] Fetching amazon/aws-sam-cli-build-image-python3.8 Docker container image...... Mounting /Users/foo/sample_app/code as /tmp/samcli/source:ro,delegated inside runtime container Build Succeeded Built Artifacts : .aws-sam/build Built Template : .aws-sam/build/template.yaml Commands you can use next ========================= [*] Invoke Function: sam local invoke [*] Deploy: sam deploy --guided Running PythonPipBuilder:ResolveDependencies Running PythonPipBuilder:CopySource
ローカルテスト実行
sam local invoke でローカルテストを実行することができます。
$ sam local invoke Invoking app.lambda_handler (python3.8) arn:aws:lambda:ap-northeast-1:716333212585:layer:appdynamics-lambda-extension:9 is already cached. Skipping download Skip pulling image and use local one: samcli/lambda:python3.8-f00964ae55accef74c51e9ff8. Mounting /Users/foo/sample_app/.aws-sam/build/SampleFunction as /var/task:ro,delegated inside runtime container [Appdynamics wrapper script] AWS_Execution_Env is [Appdynamics wrapper script] not supported, running lambda with default arguments START RequestId: db5cd0c4-3cf3-10a1-8fde-bf6711cc3df0 Version: $LATEST END RequestId: db5cd0c4-3cf3-10a1-8fde-bf6711cc3df0 REPORT RequestId: db5cd0c4-3cf3-10a1-8fde-bf6711cc3df0 Init Duration: 241.18 ms Duration: 371.69 ms Billed Duration: 400 ms Memory Size: 128 MB Max Memory Used: 27 MB {"statusCode":200,"body":"xx.xxx.xxx.xxx"}
Lambda 関数,AppDynamics Extension Layer のデプロイ
正常にグローバル IP アドレスを取得可能なことが確認できましたら,sam deploy –guided で自動デプロイを行うことができます。
$ sam deploy --guided Configuring SAM deploy ====================== Looking for config file [samconfig.toml] : Found Reading default arguments : Success Setting default arguments for 'sam deploy' ========================================= Stack Name [Python]: AWS Region [ap-northeast-1]: #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [Y/n]: y #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: y Save arguments to configuration file [Y/n]: y SAM configuration file [samconfig.toml]: SAM configuration environment [default]: Looking for resources needed for deployment: Found! Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxx A different default S3 bucket can be set in samconfig.toml Saved arguments to config file Running 'sam deploy' for future deployments will use the parameters saved above. The above parameters can be changed by modifying samconfig.toml Learn more about samconfig.toml syntax at https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-config.html Deploying with following values =============================== Stack name : Python Region : ap-northeast-1 Confirm changeset : True Deployment s3 bucket : aws-sam-cli-managed-default-samclisourcebucket-xxxxxxxxx Capabilities : ["CAPABILITY_IAM"] Parameter overrides : {} Signing Profiles : {} Initiating deployment ===================== Waiting for changeset to be created.. CloudFormation stack changeset ------------------------------------------------------------------------------------------------------------------------------------- Operation LogicalResourceId ResourceType Replacement ------------------------------------------------------------------------------------------------------------------------------------- + Add SampleFunctionRole AWS::IAM::Role N/A + Add SampleFunction AWS::Lambda::Function N/A ------------------------------------------------------------------------------------------------------------------------------------- Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:679382613873:changeSet/samcli-deploy1606793756/cda913e6-946d-4713-b0b2-71c816716825 Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y 2020-12-01 12:36:12 - Waiting for stack create/update to complete CloudFormation events from changeset ------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::IAM::Role SampleFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role SampleFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role SampleFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function SampleFunction - CREATE_IN_PROGRESS AWS::Lambda::Function SampleFunction Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function SampleFunction - CREATE_COMPLETE AWS::CloudFormation::Stack Python - ------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - Python in ap-northeast-1
AWS CLI によるLambda 関数の実行
aws lambda list-functions –query Functions[].FunctionName を実行することにより,デプロイされている Lambda 関数のリストを取得することができます。
$ aws lambda list-functions --query Functions[].FunctionName [ "Python-Function-123456ABCDEF" ]
次に,以下のように aws lambda invoke により,コマンドラインから Lambda 関数を実行することが可能です。
$ aws lambda invoke --function-name Python-Function-123456ABCDEF /dev/stdout {"statusCode": 200, "body": "xx.xxx.xxx.xxx"} "StatusCode": 200, "ExecutedVersion": "$LATEST" }
Lambda 関数実行ログの確認
sam logs コマンドで Lambda 関数のログを確認します。
sam logs -n Python-Function-123456ABCDEF ...中略... 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:41.708000 START RequestId: e0db5107-9048-45b6-a2d6-c9e586417891 Version: $LATEST 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:41.715000 2020-12-01 04:28:41,715 AppDynamics - transaction_service.py [INFO]: Starting the business transaction. 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.095000 2020-12-01 04:28:42,094 AppDynamics - transaction_service.py [INFO]: Stopping the business transaction. 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.095000 2020-12-01 04:28:42,095 AppDynamics - event_service.py [INFO]: Total number of items in the events queue are 4 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.095000 2020-12-01 04:28:42,095 AppDynamics - event_service.py [INFO]: Successfully scheduled the sending of events to downstream 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.754000 2020-12-01 04:28:42,754 AppDynamics - http_service.py [INFO]: HTTP post request was successful for url https://syd-sls-agent-api.saas.appdynamics.com/v1/events 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.756000 END RequestId: e0db5107-9048-45b6-a2d6-c9e586417891 2020/12/01/[$LATEST]6e06e51410a146fab5b645091d7ce510 2020-12-01T04:28:42.756000 REPORT RequestId: e0db5107-9048-45b6-a2d6-c9e586417891 Duration: 1041.72 ms Billed Duration: 1042 ms Memory Size: 128 MB Max Memory Used: 81 MB
AppDynamics – http_service.py [INFO]: HTTP post request was successful for url https://syd-sls-agent-api.saas.appdynamics.com/v1/events を含む行が確認でき,正常にメトリックが AppDynamics SaaS プラットフォームに送信されていることが確認できます。
Application Flow Map の確認
AppDynamics SaaS コントローラ上で,template.yaml の APPDYNAMICS_APPLICATION_NAME で指定したアプリケーションの Application Flow Map を確認すると,以下のように Lambda 関数(Python) Tier からリモートサービスとして,ifconfig.io がコールされていることが確認できました。
Lambda 関数/S3 バケット/CloudFormation スタックの削除
SAM により作成した Lambda 関数,S3 バケット, CloudFormation スタックを以下のコマンドで削除することができます(Python: CloudFormation スタック名)。
aws cloudformation delete-stack --stack-name Python
まとめ
今回は AWS SAM CLI を用い,2020年10月に導入された AppDynamics Lambda Extension で性能監視を行う,Python で書かれた Lambda 関数のデプロイ,テストを実施しました。
Extension Layer により,従来必要であった Lambda 関数のコード変更が不要となり,より利便性が高くなったと考えます。
1 コメント
2021/05/26 に Lambda Extension が GA となったようです。