LoginSignup
0

More than 3 years have passed since last update.

AppDynamics Lambda Extension による Python 関数性能監視

Last updated at Posted at 2020-12-02

この記事はシスコシステムズ有志による Cisco Systems Japan Advent Calendar 2020 (2枚目) の 3 日目として投稿しています。

2017年版: https://qiita.com/advent-calendar/2017/cisco
2018年版: https://qiita.com/advent-calendar/2018/cisco
2019年版: https://qiita.com/advent-calendar/2019/cisco
2020年版: https://qiita.com/advent-calendar/2020/cisco
2020年版(2枚目): https://qiita.com/advent-calendar/2020/cisco2

はじめに

2020年10月にプレビューとなった AWS Lambda Extensions により,コード変更なしに Lambda 関数の AppDynamics での監視が可能となりました。

AWS Lambda Extensions(プレビュー)を構築する
Step-by-Step Guide: Enhancing Lambda Performance Monitoring with AppDynamics

image.png

これまでは,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 リージョン

  • 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 関数のインストゥルメント手順の公式ドキュメントはこちらになります。

Use the AppDynamics AWS Lambda Extension to Instrument Serverless APM at Runtime

Serverless APM for AWS Lambda subscription へサブスクライブ

Serverless APM for AWS Lambda subscription から Continue to Subscribe をクリックし,

image.png

次の画面で Subscribe をクリック,

image.png

次に 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 を実行できない場合は,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"
}

ログの確認

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 がコールされていることが確認できました。

image.png

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 関数のコード変更が不要となり,より利便性が高くなったと考えます。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0