【面倒は】API Gateway + Lambda + CloudWatch LogsでPOSTされたデータのログを残す【いやだ】

LIGブログ

2018/11/9 06:00

「あぁー」

仕事していると、考えなきゃならないことっていっぱいありますよね。

「あぁー、コールバックをするAPIを作ったけど、そのテストだとか検収作業のためにコールバックの受け口が必要で、できれば手間なくコストあんまりかけることなく、ただただ単純にWebのアクセスログとPOSTされたデータだけを見られるような、そんな一時的な仕組みが割とすぐ欲しいー」みたいなのを考えなきゃならないことが。僕にはよくあります。

こんにちは。バックエンドエンジニアのまさくにです。何も考えたくない。

さて、このような必要が生じたとき、どのような手段を取ればよいのでしょうか。僕が教えて欲しいくらいなのですが、いろんな方法が考えられると思います。Webサーバーが一台あってPHPなんかが動いていれば楽勝ですね。でもこんなちょっとした役割のためのサーバーが見つからない。

じゃあHerokuとかNetlifyとかでどうにかならなんかなーって考えたんですけど、リポジトリ一個用意してデプロイー? 永続データどーすっかなーって考えるとちょっと面倒な気もする。じゃあログかーCloudWatch Logsかなー、Lambdaかなー、というのが以下の方法です。いきましょう。

全体像



簡単ですね。

今回はAPIのコールバックを受けるような用途を想定しているので、どっかからAPI GatewayがPOSTで叩かれ、Lambdaが起動され、CloudWatch LogsにPOSTデータが載るようなものを考えています。認証などは設けないので、秘匿データの扱いにはご注意ください。

Lambda部分

まずLambdaでPOSTデータをCloudWatch Logsに書き出すスクリプトを書いておきます。LambdaはデフォルトでCloudWatch Logsにログを書き出すようになっているので、IAM設定する必要はありません。(自動で作ってくれます)下記のようにLambdaを作ります。



この条件で作成し、あとはFunctionを書いておきます。今回はNode.js 8.1.0を選んでいるので下記のように。eventの中の body-json にPOSTデータが入ってくるのですが、これは後で設定します。それにしてもconsole.logでCloudWatch Logsに入れてくれるのはとても楽ですね。
ここまで書いたら右上の「保存」で保存しておきましょう。一応「テストイベントの作成」からテストを作って、実行してみると下記のようになります。ちゃんと動いているようです。



まだデータが入ってきていないので、ログ出力の部分で「callback response undefined」となっていますが、これをAPI Gatewayとつなげてログ出力できるようにします。

API Gateway部分



上記のように新しくAPI Gatewayを作りましょう。

リソースを作成しときます。API Gatewayでリソースというのは要するにURLを追加するということになります。このURLにアクセスすることでLambdaを起動させるということですね。下記では /reciever というリソースを追加しています。



で、このリソースに対してメソッドの追加もしておきます。今回はデータを送るのでPOST。Lambda関数に先ほど作成した関数を設定しておきましょう。



この時点で、テストをすると下記のようにLambdaからレスポンスが帰ってくると思います。テストでLambdaとの疎通が確認できたら、一度デプロイしてしまいましょう。下記のようにステージを適当に作成し、デプロイを行います。



これでAPI Gateway用のURLが発行されるので、POSTができるようになります。何を使ってもいいんですが、下記のようなコマンドでPOSTしてみましょう。
ちゃんとLambdaからレスポンスが帰ってきているのが確認できますね。でもこれだけだとCloudwatch Logsには何も書かれません。「callback response undefined」のままだと思います。POSTデータを渡すには、API Gatewayでもう少し設定が必要です。

もう一度API GatewayのPOSTメソッドを開き、「統合メソッド」を開いてください。その「マッピングテンプレート」を下記のように設定します。


これで保存すれば設定完了です。何をしてるかというとAPI GatewayはLambdaを起動するのですが、デフォルトでPOSTデータなどを渡しません。それを渡すためのマッピングを書く必要があり、上記の設定を行うことで body-json にデータが入るようになります。

試してみる

もう一度curlで実行してみます。ちなみにapplication/jsonだった時のマッピングテンプレートを書いたので Content-Type で指定しないとLambdaにデータが渡りません。
Cloudwatch Logsを見ましょう。ログストリームに下記のようなログが入ってくるのではないでしょうか。



やったぜー! 成功だぜー! 無料枠だぜー! という感じで目的を達することができました。でも絶対にもっと簡単にできる気がするので、皆さまからのグッドアイデアお待ちしてます。まさくにでした。

あなたにおすすめ