aws-lambda-powertools を試してみる(Logger 編)
概要
記事一覧はこちらです。
Twitter で Simplifying serverless best practices with Lambda Powertools の記事を見かけました。Python で Lambda を作成する時に Logging、Tracing、Metrics の機能の実装を助けてくれるライブラリとのこと。
記事は SAM で実装されていたので Serverless Framework で実装して動作を確認してみます。Logger で1回(今回)、Tracer で2回の計3回に分けて書きます。Metrics は使い方(というか何が便利になるのか)が今ひとつ分からなかったので書きません。
参照したサイト・書籍
Simplifying serverless best practices with Lambda Powertools
https://aws.amazon.com/jp/blogs/opensource/simplifying-serverless-best-practices-with-lambda-powertools/AWS Lambda Powertools Python
https://awslabs.github.io/aws-lambda-powertools-python/aws-samples / aws-serverless-shopping-cart
https://github.com/aws-samples/aws-serverless-shopping-cart/tree/master/backend/shopping-cart-service- Python で書かれた Serverless のサンプル。今回の記事とは直接関係ありませんが、後で見たいので残しておきます。
Serverless Framework v1.41 - X-Ray for API Gateway, Invoke Local with Docker Improvements & More
https://www.serverless.com/blog/framework-release-v141/オブザーバビリティ(可観測性)がなぜ必要だと考えるのか
https://ymotongpoo.hatenablog.com/entry/2019/03/25/084500CloudWatch Logs Insights を使用したログデータの分析
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AnalyzingLogData.html地味にイイネ!Amazon CloudWatch Logs Insightsで効率的に調査しよう!
https://blog.ecbeing.tech/entry/2019/09/19/124352CloudWatch Logs Insights でApacheのアクセスログを確認する
https://dev.classmethod.jp/articles/cwinsights-apache/
目次
- lambda-powertools-project プロジェクトを作成する
- sample_service サブプロジェクトを作成する
- requirements.txt を作成する
- serverless.yml に POWERTOOLS 用の環境変数と X-Ray を有効にする設定を追加する
- Logging の機能を試してみる
手順
lambda-powertools-project プロジェクトを作成する
以下の手順で lambda-powertools-project プロジェクトを作成します。具体的な手順は IntelliJ IDEA+Node.js+npm+serverless framework+Python の組み合わせで開発環境を構築して AWS Lambda を作成してみる 参照。
- lambda-powertools-project の Empty Project を作成する。
- Python の仮想環境を作成する。
- Serverless Framework をローカルインストールする。
- .envrc を作成する。
- aws-lambda-powertools は deploy 時にアップロードしないと使用できないので serverless-python-requirements をインストールします。
npm install --save-dev serverless-python-requirements
- Tracing の機能を試すのに Lambda から別のサービスを呼び出すので boto3 をインストールします。aws-lambda-powertools もインストールします。
pip install boto3
pip install aws-lambda-powertools
sample_service サブプロジェクトを作成する
プロジェクトのルートディレクトリの下で npx sls create --template aws-python3 --path sample_service
を実行して sample_service サブプロジェクトを作成します。
requirements.txt を作成する
deploy 時に aws-lambda-powertools もアップロードするために sample_service ディレクトリの下に requirements.txt を作成して以下の内容を記述します。
aws-lambda-powertools==1.0.0
serverless.yml に POWERTOOLS 用の環境変数と X-Ray を有効にする設定を追加する
sample_service/serverless.yml を以下のように変更します。
service: sample-service plugins: - serverless-python-requirements custom: pythonRequirements: dockerizePip: true provider: name: aws runtime: python3.8 stage: dev region: ap-northeast-1 environment: # aws-lambda-powertools 用環境変数 LOG_LEVEL: INFO POWERTOOLS_LOGGER_LOG_EVENT: true POWERTOOLS_METRICS_NAMESPACE: lambda-powertools-project POWERTOOLS_SERVICE_NAME: sample-service tracing: apiGateway: true lambda: true ..........
- グローバルな環境変数は provider.environment に記述すればよいので、ここに POWERTOOLS 用の環境変数のうち以下の4つを設定します。
- LOG_LEVEL
- POWERTOOLS_LOGGER_LOG_EVENT
- POWERTOOLS_METRICS_NAMESPACE
- POWERTOOLS_SERVICE_NAME
- X-Ray の設定は provider.tracing に記述するので、
apiGateway: true
、lambda: true
を設定します。
Logging の機能を試してみる
今回は以下の JSON Schema のメッセージを送信します(sample_service ディレクトリの下に msg_schema.json というファイルを作成しその中に記述します)。
{ "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "orderedItem": { "type": "object", "properties": { "orderItemNumber": { "type": "string", "pattern": "^[0-9]+$" }, "orderQuantity": { "type": "integer", "minimum": 0, "maximum": 999 }, "productID": { "type": "string", "pattern": "^[0-9]+$" }, "category": { "type": "string", "enum": [ "book", "camera", "computer" ] }, "price": { "type": "integer", "minimum": 1 } }, "required": [ "orderItemNumber", "orderQuantity", "productID", "category", "price" ] } }, "title": "Order", "type": "object", "properties": { "orderNumber": { "type": "string", "pattern": "^[0-9]+$" }, "orderDate": { "type": "string", "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$" }, "isGift": { "type": "boolean" }, "orderedItem": { "type": "array", "minItems": 1, "maxItems": 3, "uniqueItems": true, "items": { "$ref": "#/definitions/orderedItem" } } }, "required": [ "orderNumber", "orderDate", "orderedItem" ] }
メッセージのサンプルです。
{ "orderNumber": "1", "orderDate": "2020-06-28", "isGift": false, "orderedItem": [ { "orderItemNumber": "1", "orderQuantity": 3, "productID": "1001", "category": "book", "price": 3800 }, { "orderItemNumber": "2", "orderQuantity": 1, "productID": "3052", "category": "camera", "price": 150000 } ] }
sample_service の下の handler.py を apigw_handler.py にリネームし、以下の内容を記述します。
import json from aws_lambda_powertools import Logger logger = Logger() # @logger.inject_lambda_context を付けておくとログ出力時に context にセットされている # function_name 等の情報がセットされる # Capturing context Lambda info # https://awslabs.github.io/aws-lambda-powertools-python/core/logger/#capturing-context-lambda-info @logger.inject_lambda_context def recv_msg(event, context): logger.debug(event['body']) request_body = json.loads(event['body']) logger.info({ "orderNumber": request_body['orderNumber'], "orderDate": request_body['orderDate'] }) body = { "message": "Go Serverless v1.0! Your function executed successfully!", "input": event } response = { "statusCode": 200, "body": json.dumps(body) } return response
sample_service/serverless.yml の functions の記述を以下の内容に変更します。
functions: recvMsg: handler: apigw_handler.recv_msg events: - http: path: recv-msg method: post cors: true request: schema: application/json: ${file(msg_schema.json)}
deploy します。
Postman からサンプルメッセージを送信すると 200 OK が返ってきました。
試した結果としては、
まずログのメッセージフォーマットが JSON になり、logger のメソッドに渡した文字列は message に出力されます。JSON フォーマットになることで CloudWatch Logs Insights で検索しやすくなります。
Lambda に @logger.inject_lambda_context
を付与しておくと、出力されるログに引数 context にセットされている function_name 等の情報が追加されます。
@logger.inject_lambda_context
が付与されていて、かつ環境変数 POWERTOOLS_LOGGER_LOG_EVENT が true に設定されていると、Lambda が呼び出された時に decorate のログ(API Gateway から呼び出された Lambda だとアクセス時の HTTPヘッダ等)が出力されます。環境変数 POWERTOOLS_LOGGER_LOG_EVENT のデフォルト値が false なので DEBUG 用?
環境変数 LOG_LEVEL で出力するログのレベルを調整可能です。今は LOG_LEVEL: INFO
の設定なので INFO のログだけ出ていますが(環境変数 POWERTOOLS_LOGGER_LOG_EVENT は false にしています)、
sample_service/serverless.yml で functions.recvMsg.environment に LOG_LEVEL: DEBUG
を設定した後、deploy し直してからメッセージを送信すると、
provider: name: aws runtime: python3.8 stage: dev region: ap-northeast-1 environment: # aws-lambda-powertools 用環境変数 LOG_LEVEL: INFO POWERTOOLS_LOGGER_LOG_EVENT: false POWERTOOLS_METRICS_NAMESPACE: lambda-powertools-project POWERTOOLS_SERVICE_NAME: sample-service tracing: apiGateway: true lambda: true functions: recvMsg: handler: apigw_handler.recv_msg events: - http: path: recv-msg method: post cors: true request: schema: application/json: ${file(msg_schema.json)} environment: LOG_LEVEL: DEBUG
DEBUG のログも出力されます。
履歴
2020/07/05
初版発行。