はじめに
AWS上でAPI GatewayとLambdaを使ってWEBサービスを作るときに便利なPythonフレームワークのAWS Chalice。便利ポイントの一つが、chalice local
コマンド一発で、手元のPC(ローカル)にWEBサーバが立ち上がって、AWS上で動かすものと同じものが動いてしまう、というところ1。テストとデバッグがめちゃくちゃ捗ります。
課題
という便利なchalice local
なんですが、ローカルで動かしていることをコードで判定する直接的な方法が無さそうだったので、考えてみました。
きっかけは、実施例にも示したとおり、AWS上で動かすときとローカルで動かすときでログのフォーマットを変えようとしたことです2。
解決方法
以下でできます。環境変数を活用します3。
- chaliceの設定ファイル(config.json)で
chalice local
用のstageを定義し、定義したstageに適当な環境変数を設定する。 -
chalice local
するときには、上記で定義したstageを--stage
オプションで指定する。
これにより、コード側では、環境変数の存在をチェックすることで、chalice local
している(ローカルで実行している)かどうかを判定できるようになります。
実施例
設定ファイル
{
"version": "2.0",
"app_name": "testapp",
"environment_variables": {
},
"stages": {
"dev": {
"api_gateway_stage": "api"
},
"local": {
"environment_variables": {
"IS_LOCAL": "true"
}
}
}
}
local
というstageに、IS_LOCAL
という環境変数をセットしています。
コード本体
import logging
import os
# setup logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logformat = (
'[%(levelname)s] %(asctime)s.%(msecs)dZ (%(aws_request_id)s) '
'%(filename)s:%(funcName)s[%(lineno)d] %(message)s'
)
if os.environ.get('IS_LOCAL'):
logformat = (
'[%(levelname)s] %(asctime)s.%(msecs)dZ '
'%(filename)s:%(funcName)s[%(lineno)d] %(message)s'
)
formatter = logging.Formatter(logformat, '%Y-%m-%dT%H:%M:%S')
for handler in logger.handlers:
handler.setFormatter(formatter)
AWS上で動かすときとローカルで動かすときでログのフォーマットを変更しています2。
実行方法
$ chalice local --stage local
chalice local
するときには、定義したstageを--stage
オプションで指定します。
おわりに
この方法、chalice local
に必ず--stage
オプションを付ける必要があるところがいまいちですが、課題は確かに解決できているので活用してます。
ログフォーマット以外での活用例があれば知りたい。。。(-;
-
Tutorial: Local Mode - Quickstart and Tutorial — Python Serverless Microframework for AWS ↩
-
すごく細かい話なんですが、
logging.Formatter
に渡すフォーマット情報のうち、aws_request_id
はlamba上で動かすときにしか値が得られません。chalice local
するときにこの情報を使っているとエラーが出てしまうので、AWS上かローカルかでログのフォーマットを変えてあげたくなります。 ↩ ↩2 -
Environment variables on chalice local · Issue #748 · aws/chalice ↩