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

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

まさくに

まさくに

「あぁー」

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

「あぁー、コールバックをする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に入れてくれるのはとても楽ですね。

exports.handler = (event, context, callback) => {
    console.log("callback response " + JSON.stringify(event['body-json']));
    callback(null, {"message":"seikou_daze"});
};

ここまで書いたら右上の「保存」で保存しておきましょう。一応「テストイベントの作成」からテストを作って、実行してみると下記のようになります。ちゃんと動いているようです。

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

API Gateway部分

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

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

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

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

これでAPI Gateway用のURLが発行されるので、POSTができるようになります。何を使ってもいいんですが、下記のようなコマンドでPOSTしてみましょう。

$ curl -X POST -H 'Content-Type: application/json' -d '{"hey": "yo!"}' https://xyz.execute-api.ap-northeast-1.amazonaws.com/test-receiver-999-105/receiver
{"message":"seikou_daze"}

ちゃんとLambdaからレスポンスが帰ってきているのが確認できますね。でもこれだけだとCloudwatch Logsには何も書かれません。「callback response undefined」のままだと思います。POSTデータを渡すには、API Gatewayでもう少し設定が必要です。

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

{
    "body-json" : $input.json('$') 
}

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

試してみる

もう一度curlで実行してみます。ちなみにapplication/jsonだった時のマッピングテンプレートを書いたので Content-Type で指定しないとLambdaにデータが渡りません。

curl -X POST -H 'Content-Type: application/json' -d '{"hey": "yo!"}' https://xyz.execute-api.ap-northeast-1.amazonaws.com/test-receiver-999-105/receiver
{"message":"seikou_daze"}

Cloudwatch Logsを見ましょう。ログストリームに下記のようなログが入ってくるのではないでしょうか。

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

LIGはWebサイト制作を支援しています。ご興味のある方は事業ぺージをぜひご覧ください。

Webサイト制作の実績・料金を見る

この記事のシェア数

まさくに
まさくに バックエンドエンジニア / 伊藤 正訓

漢字で書くと正訓。バックエンドのエンジニアです。静岡と石川に住んだことがあり、現在は千葉に住んでいます。誰かが作ったシステムに対しては、正常系だけを通るように並列処理やデッドロックが起きそうな処理を避けて操作する職業病があります。好きな色は紫、好きなキーボードの位置は「i」、好きなご当地ヒーローはセッシャー1です。

このメンバーの記事をもっと読む
デザイン力×グローバルな開発体制でDXをトータル支援
お問い合わせ 会社概要DL