[PYTHON] [AWS] Essayez de tracer API Gateway + Lambda avec X-Ray

Qu'est-ce que la radiographie

Un service d'analyse et de débogage des applications distribuées. Cliquez ici pour plus de détails. AWS X-Ray

supposition

Encore une fois, je vais essayer de créer un exemple avec la configuration suivante.

Pour des connaissances de base telles que SAM, veuillez vous référer ici.

Faisons un échantillon

Création de projet

Comme d'habitude, nous allons créer un projet basé sur Hello World dans SAM.

$ sam init --runtime=python3.8
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Project name [sam-app]:

Cloning app templates from https://github.com/awslabs/aws-sam-cli-app-templates.git

AWS quick start application templates:
	1 - Hello World Example
	2 - EventBridge Hello World
	3 - EventBridge App from scratch (100+ Event Schemas)
	4 - Step Functions Sample App (Stock Trader)
	5 - Elastic File System Sample App
Template selection: 1

-----------------------
Generating application:
-----------------------
Name: sam-app
Runtime: python3.8
Dependency Manager: pip
Application Template: hello-world
Output Directory: .

Next steps can be found in the README file at ./sam-app/README.md

Ajout de rayons X

Ajouter un décorateur au code source

Tout d'abord, ajoutez le décorateur X-Ray au code. Essayez ce qui suit, y compris la refactorisation du hello_world / app.py généré par défaut.

hello_world/app.py


import json
from aws_xray_sdk.core import xray_recorder

@xray_recorder.capture('hello world')
def lambda_handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "hello world",
        })
    }

Importer le SDK

Pour importer la bibliothèque X-Ray SDK dans Lambda, modifiez hello_world / requirements.txt comme suit.

hello_world/requirements.txt


aws-xray-sdk

Modifier le modèle SAM

Enfin, pour activer la fonction Lambda et le traçage de la passerelle API, modifiez la partie Globals comme suit.

template.avant la modification yml


Globals:
  Function:
    Timeout: 3

template.Après correction yml


Globals:
  Function:
    Timeout: 3
    Tracing: Active
  Api:
    TracingEnabled: True

Construire

$ sam build
Building function 'HelloWorldFunction'
Running PythonPipBuilder:ResolveDependencies
Running PythonPipBuilder:CopySource

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

Déployer

$ sam deploy --guided

Configuring SAM deploy
======================

	Looking for samconfig.toml :  Found
	Reading default arguments  :  Success

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [sam-app]:
	AWS Region [us-east-1]: 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
	HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
	Save arguments to samconfig.toml [Y/n]: y

	Looking for resources needed for deployment: Found!

		Managed S3 bucket: aws-sam-cli-managed-default-samclisourcebucket-1rzppw621dkka
		A different default S3 bucket can be set in samconfig.toml

	Deploying with following values
	===============================
	Stack name                 : sam-app
	Region                     : ap-northeast-1
	Confirm changeset          : True
	Deployment s3 bucket       : aws-sam-cli-managed-default-samclisourcebucket-1rzppw621dkka
	Capabilities               : ["CAPABILITY_IAM"]
	Parameter overrides        : {}

Initiating deployment
=====================

	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                 : sam-app
	Region                     : ap-northeast-1
	Confirm changeset          : True
	Deployment s3 bucket       : aws-sam-cli-managed-default-samclisourcebucket-1rzppw621dkka
	Capabilities               : ["CAPABILITY_IAM"]
	Parameter overrides        : {}

Initiating deployment
=====================
HelloWorldFunction may not have authorization defined.
Uploading to sam-app/8476bddd8c14756a7c801a61352b828d.template  1142 / 1142.0  (100.00%)

Waiting for changeset to be created..

CloudFormation stack changeset
------------------------------------------------------------------------------------------------
Operation                        LogicalResourceId                ResourceType
------------------------------------------------------------------------------------------------
+ Add                            HelloWorldFunctionHelloWorldPe   AWS::Lambda::Permission
                                 rmissionProd
+ Add                            HelloWorldFunctionRole           AWS::IAM::Role
+ Add                            HelloWorldFunction               AWS::Lambda::Function
+ Add                            ServerlessRestApiDeployment47f   AWS::ApiGateway::Deployment
                                 c2d5f9d
+ Add                            ServerlessRestApiProdStage       AWS::ApiGateway::Stage
+ Add                            ServerlessRestApi                AWS::ApiGateway::RestApi
------------------------------------------------------------------------------------------------

Changeset created successfully. arn:aws:cloudformation:ap-northeast-1:************:changeSet/samcli-deploy1597324152/18c44433-12d1-4e03-9fb8-00737d018991


Previewing CloudFormation changeset before deployment
======================================================
Deploy this changeset? [y/N]: y

2020-08-13 22:09:28 - Waiting for stack create/update to complete

CloudFormation events from changeset
-------------------------------------------------------------------------------------------------
ResourceStatus           ResourceType             LogicalResourceId        ResourceStatusReason
-------------------------------------------------------------------------------------------------
CREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldFunctionRole   -
CREATE_IN_PROGRESS       AWS::IAM::Role           HelloWorldFunctionRole   Resource creation
                                                                           Initiated
CREATE_COMPLETE          AWS::IAM::Role           HelloWorldFunctionRole   -
CREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldFunction       -
CREATE_IN_PROGRESS       AWS::Lambda::Function    HelloWorldFunction       Resource creation
                                                                           Initiated
CREATE_COMPLETE          AWS::Lambda::Function    HelloWorldFunction       -
CREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        Resource creation
                         pi                                                Initiated
CREATE_IN_PROGRESS       AWS::ApiGateway::RestA   ServerlessRestApi        -
                         pi
CREATE_COMPLETE          AWS::ApiGateway::RestA   ServerlessRestApi        -
                         pi
CREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -
                         yment                    yment47fc2d5f9d
CREATE_IN_PROGRESS       AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   Resource creation
                         yment                    yment47fc2d5f9d          Initiated
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldFunctionHell   Resource creation
                         n                        oWorldPermissionProd     Initiated
CREATE_IN_PROGRESS       AWS::Lambda::Permissio   HelloWorldFunctionHell   -
                         n                        oWorldPermissionProd
CREATE_COMPLETE          AWS::ApiGateway::Deplo   ServerlessRestApiDeplo   -
                         yment                    yment47fc2d5f9d
CREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   -
                                                  tage
CREATE_COMPLETE          AWS::Lambda::Permissio   HelloWorldFunctionHell   -
                         n                        oWorldPermissionProd
CREATE_IN_PROGRESS       AWS::ApiGateway::Stage   ServerlessRestApiProdS   Resource creation
                                                  tage                     Initiated
CREATE_COMPLETE          AWS::ApiGateway::Stage   ServerlessRestApiProdS   -
                                                  tage
CREATE_COMPLETE          AWS::CloudFormation::S   sam-app                  -
                         tack
-------------------------------------------------------------------------------------------------

CloudFormation outputs from deployed stack
-------------------------------------------------------------------------------------------------
Outputs
-------------------------------------------------------------------------------------------------
Key                 HelloWorldFunctionIamRole
Description         Implicit IAM Role created for Hello World function
Value               arn:aws:iam::************:role/sam-app-HelloWorldFunctionRole-IIPXQC9S1XKJ

Key                 HelloWorldApi
Description         API Gateway endpoint URL for Prod stage for Hello World function
Value               https://tws0qc6nbc.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/

Key                 HelloWorldFunction
Description         Hello World Lambda Function ARN
Value               arn:aws:lambda:ap-northeast-1:************:function:sam-app-
HelloWorldFunction-1OH75PSLQUSLC
-------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

Courir

curl https://tws0qc6nbc.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}

Réussi.

Vérification

Maintenant, vérifions la carte du service X-Ray, les traces et les analyses dans la console de gestion.

Service Map

Vous pouvez vérifier comment il est appelé depuis le client, API Gateway et Lambda dans cet ordre, ainsi que la latence de chacun.

xray1.png

Traces

Ici, vous pouvez vérifier l'état de la trace. Ici, vous pouvez filtrer en fonction de chaque condition.

xray2.png

Analytique

Enfin, comme son nom l'indique, l'analyse peut effectuer une variété d'analyses et de comparaisons.

xray3.png

Essayez de suivre les services AWS

Trouvons maintenant le service AWS. Cette fois, j'ajouterai une trace pour PutItem à DynamoDB.

Pour plus de détails, reportez-vous à «[AWS] Try to create an API Gateway + Lambda + DynamoDB sample with Serverless Application Model (SAM)». Je voudrais expliquer uniquement la partie liée à la radiographie avec des points.

Ajouter du code

Tout d'abord, créez un répertoire pour Function séparément de HelloWorld et créez-y des fichiers.

$ mkdir sam_ddb
$ touch sam_ddb/app.py
$ touch sam_ddb/requirements.txt

Tout d'abord, le corps de la fonction Lambda, mais la partie importante ici est la partie patch ['boto3']. En faisant cela, vous pourrez suivre les appels de service boto3 AWS.

sam_ddb/app.py


import json
import boto3
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch
from datetime import datetime

patch(['boto3'])

@xray_recorder.capture('put_item ddb')
def lambda_handler(event, context):
    event_body = json.loads(event["body"])
    dynamodb = boto3.resource("dynamodb")

    table = dynamodb.Table("Demo")
    table.put_item(
        Item={
            "Key": event_body["key"],
            "CreateDate": datetime.utcnow().isoformat()
        }
    )

    return {
        "statusCode": 200,
        "body": json.dumps({
            "message": "succeeded",
        }),
    }

sam_ddb/requirements.txt


aws-xray-sdk
boto3

Enfin, éditez template.yml. Les parties qui doivent être modifiées sont «Resources» et «Outputs». Veuillez noter que le rôle IAM nécessite des autorisations pour X-Ray.

template.yml avant le changement


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    Tracing: Active
  Api:
    TracingEnabled: True

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn

template.après avoir changé yml


AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  sam-app

  Sample SAM Template for sam-app

# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
  Function:
    Timeout: 3
    Tracing: Active
  Api:
    TracingEnabled: True

Resources:
  DynamoTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Demo
      AttributeDefinitions:
        - AttributeName: Key
          AttributeType: S
        - AttributeName: CreateDate
          AttributeType: S
      KeySchema:
        - AttributeName: Key
          KeyType: HASH
        - AttributeName: CreateDate
          KeyType: RANGE
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5

  HelloWorldFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /hello
            Method: get

  SamDdbFunction:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt SamDdbFunctionIamRole.Arn
      CodeUri: sam_ddb/
      Handler: app.lambda_handler
      Runtime: python3.8
      Events:
        SamDdb:
          Type: Api
          Properties:
            Path: /ddb
            Method: post

  SamDdbFunctionIamRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - 'lambda.amazonaws.com'
            Action:
              - 'sts:AssumeRole'
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/CloudWatchLogsFullAccess'
      Policies:
        - PolicyName: 'SamDdbPolicy'
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:PutItem
                Resource: !GetAtt DynamoTable.Arn
              - Effect: Allow
                Action:
                  - xray:PutTraceSegments
                  - xray:PutTelemetryRecords
                Resource: '*'

Outputs:
  # ServerlessRestApi is an implicit API created out of Events key under Serverless::Function
  # Find out more about other implicit resources you can reference within SAM
  # https://github.com/awslabs/serverless-application-model/blob/master/docs/internals/generated_resources.rst#api
  HelloWorldApi:
    Description: "API Gateway endpoint URL for Prod stage for Hello World function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/hello/"
  HelloWorldFunction:
    Description: "Hello World Lambda Function ARN"
    Value: !GetAtt HelloWorldFunction.Arn
  HelloWorldFunctionIamRole:
    Description: "Implicit IAM Role created for Hello World function"
    Value: !GetAtt HelloWorldFunctionRole.Arn
  SamDdbApi:
    Description: "API Gateway endpoint URL for Prod stage for SAM DDB function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/ddb/"

Construire et déployer

Exécutez sam build et sam deploy --guided. (Détails omis)

Courir

Puisque nous avons ajouté une API cette fois, nous appellerons également l'API Hello World à des fins de comparaison.

$ curl https://fp8nyhpv87.execute-api.ap-northeast-1.amazonaws.com/Prod/hello/
{"message": "hello world"}

Ensuite, appelons l'API Post pour écrire dans DynamoDB.

$ curl -X POST -H "Content-Type: application/json" -d '{"key": "demo-data"}' https://fp8nyhpv87.execute-api.ap-northeast-1.amazonaws.com/Prod/ddb/
{"message": "succeeded"}

Confirmation de la radiographie

Tout d'abord, à partir de la carte des services. L'arrangement est tordu pour une raison quelconque, mais vous pouvez voir que la partie d'accès à DynamoDB est découpée et affichée. Vous pouvez voir que la partie écriture de la base de données prend 620 ms.

xray4.png

Il en va de même pour les traces. La pièce DynamoDB peut être tracée indépendamment.

xray5.png

Vérifiez DynamoDB au cas où

Les données sont parfaitement enregistrées.

ddb.png

Résumé

Le traçage avec X-Ray permet diverses analyses. Vous pouvez facilement l'ajouter après coup, mais si possible, nous vous recommandons de l'introduire dès le début.

Exemple de référentiel de code

https://github.com/hito-psv/sam-demo-003

Recommended Posts

[AWS] Essayez de tracer API Gateway + Lambda avec X-Ray
[AWS] Créer une API avec API Gateway + Lambda
[AWS SAM] Créer une API avec DynamoDB + Lambda + API Gateway
LINE BOT avec Python + AWS Lambda + API Gateway
Créez rapidement une API avec Python, lambda et API Gateway à l'aide d'AWS SAM
API REST facile avec API Gateway / Lambda / DynamoDB
Envoyer les images prises avec ESP32-WROOM-32 vers AWS (API Gateway → Lambda → S3)
Afficher les images sur S3 avec API Gateway + Lambda
Version Amazon API Gateway et AWS Lambda Python
Essayez les destinations AWS Lambda
AWS CDK-Lambda + API Gateway (Python)
PyTorch avec AWS Lambda [importation Lambda]
Prenez rapidement une chaîne de requête avec API Gateway-> Lambda (Python)
[AWS] Essayez d'ajouter la bibliothèque Python à la couche avec SAM + Lambda (Python)
Essayez d'automatiser le démarrage / l'arrêt des instances EC2 avec AWS Lambda
Essayez de fournir des variables d'environnement AWS Lambda?
Notifier HipChat avec AWS Lambda (Python)
J'ai essayé ChatOps avec Slack x API Gateway x Lambda (Python) x RDS
[Python] J'ai écrit une API REST en utilisant AWS API Gateway et Lambda.
Comment créer une API de machine learning sans serveur avec AWS Lambda
[AWS] Utilisation de fichiers ini avec Lambda [Python]
J'ai essayé de supprimer régulièrement les mauvais tweets avec l'API AWS Lambda + Twitter
Essayez d'implémenter XOR avec l'API fonctionnelle Keras
J'ai essayé de créer un LINE BOT "Sakurai-san" avec API Gateway + Lambda
Présentation du mécanisme Twilio # 3-1 - Procédure pas à pas de mise en œuvre de la passerelle API API + Lambda (partie 1)
[AWS] Associez Lambda et S3 à boto3
Connectez-vous à s3 avec AWS Lambda Python
[AWS] Faites des choses de type SSI avec S3 / Lambda
Essayez d'attribuer ou de changer avec Python: lambda
Je viens de faire FizzBuzz avec AWS Lambda
Essayez Tensorflow avec une instance GPU sur AWS
Grattage sans serveur régulier avec AWS lambda + scrapy Part 1.8
Application sans serveur avec AWS SAM! (APIGATEWAY + Lambda (Python))
Essayez l'authentification OAuth Slack avec Flask (API Slack V2)
J'ai essayé de connecter AWS Lambda à d'autres services
Automatisation de la construction de l'infrastructure avec CloudFromation + troposphère + AWS Lambda
Transmettre Cognito Id à Lambda via API Gateway
Remarque pour le traitement des données POST en se connectant à Lambda via la passerelle API d'AWS (API HTTP)
Pages HTML dynamiques créées avec AWS Lambda et Python
[AWS] Play with Step Functions (SAM + Lambda) Part.3 (Branch)
Essayez de créer une API RESTful avec MVC à l'aide de Flask 1.0.2
Déployer la fonction Python 3 avec Serverless Framework sur AWS Lambda
Créer une couche pour AWS Lambda Python dans Docker
[AWS] Play with Step Functions (SAM + Lambda) Part.1 (Basic)
Essayez d'automatiser la surveillance du nombre de Qiita avec Lambda + DynamoDB + CloudWatch
Je veux AWS Lambda avec Python sur Mac!
Gérer la rétention des groupes de journaux Amazon CloudWatch avec AWS Lambda
Créez des tweets ordinaires comme une flotte avec AWS Lambda et Python
[AWS] Play with Step Functions (SAM + Lambda) Part.2 (Paramètres)
Création d'un BOT «Présentation non officielle du produit remis à neuf par Apple» avec l'API de messagerie LINE (v2) + API Gateway + lambda (python)