Amazon S3 Event Notifications + sinatra を利用してS3に追加されるファイルのログを取得


S3に新しい機能が追加されましたね（こちら[【AWS発表】S3の新しいイベント通知機能](http://aws.typepad.com/aws_japan/2014/11/s3-event-notification.html)）。

早速クラスメソッドさんなど使い方を公開されて下さり、ありがたい限りです。（[[AWS新機能] Amazon S3 Event Notificationsを使ってみた #reinvent](http://dev.classmethod.jp/cloud/amazon-s3-event-notifications/)）

私も早速利用してみようと思います。まずSNSTopicの設定やS3の設定などは上記クラスメソッドさんを参考にしていただけたら…（手抜き…
あ、SNSでサブスクリプションを作成するときは

* Protocol: http
* Endpoint: http://Sinatraが動いているサーバ:4567/s3notification
 
としてください。

SNSのHTTP通知をSinatraで作成したアプリで受けて、イベントの内容をログに残そうってかんじです。
ただ、Rubyのloggerを利用しているだけなので凝ったログにしてるわけじゃないです。

内容は簡単で
1. SinatraでSNSのサブスクリプションを受ける、承認する。
2. S3にファイルが追加された通知を受け取る。
3. 内容をログに書き出す。 

だけ

```rb
# SNS のクライアントロード
SNS = Aws::SNS::Client.new(region: 'ap-northeast-1')

# SNS通知の受け口
post '/s3notification' do
  notif = JSON.parse(request.body.read)
  
  case notif['Type']
  # サブスクリプション認証のリクエストを受け取ったので承認する。
  when "SubscriptionConfirmation" then
    SNS.confirm_subscription(:topic_arn => notif['TopicArn'],
                             :token => notif['Token'],
                             :authenticate_on_unsubscribe => 'true'
    )
  # 通知を受け取ったのでリクエストのmessageをログとして出力
  when "Notification" then
   LOGGER.info(notif['Message'])  
  else
    LOGGER.info(notif)  
  end
end

```
実際のコードはこちら https://github.com/mominosin/s3-notification-receiver

実際にS3 Notificationを設定したS3に test01.txt を配置した時に飛んできたログ

```
I, [2014-11-14T17:48:44.411781 #24933]  INFO -- : {"Records":[{"eventVersion":"2.0","eventSource":"aws:s3","awsRegion":"ap-northeast-1","eventTime":"2014-11-14T17:46:17.469Z","eventName":"ObjectCreated:Put","userIdentity":{"principalId":"A3336BHUMP8V3P"},"requestParameters":{"sourceIPAddress":"10.114.229.8"},"responseElements":{"x-amz-request-id":"08E05D2DDE657BF4","x-amz-id-2":"ngr1FgdrUyg4MiAPwwYdOKxGMxgNVfPGJ9R9rBuhr6aJ0w31v+i/CYw4J2RlhpWh"},"s3":{"s3SchemaVersion":"1.0","configurationId":"s3-notification","bucket":{"name":"s3-notif-test","ownerIdentity":{"principalId":"A3336BHUMP8V3P"},"arn":"arn:aws:s3:::s3-notif-test"},"object":{"key":"test01.txt","size":4815,"eTag":"3a777152a1477fe290405dc5b9b0f59c"}}}]}
```
みずらいっすねjqにかけてみました。

```rb
{
  "Records": [
    {
      "s3": {
        "object": {
          "eTag": "3a777152a1477fe290405dc5b9b0f59c",
          "size": 4815,
          "key": "test01.txt"
        },
        "bucket": {
          "arn": "arn:aws:s3:::s3-notif-test",
          "ownerIdentity": {
            "principalId": "A3336BHUMP8V3P"
          },
          "name": "s3-notif-test"
        },
        "configurationId": "s3-notification",
        "s3SchemaVersion": "1.0"
      },
      "eventVersion": "2.0",
      "eventSource": "aws:s3",
      "awsRegion": "ap-northeast-1",
      "eventTime": "2014-11-14T17:46:17.469Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "A3336BHUMP8V3P"
      },
      "requestParameters": {
        "sourceIPAddress": "10.114.229.8"
      },
      "responseElements": {
        "x-amz-id-2": "ngr1FgdrUyg4MiAPwwYdOKxGMxgNVfPGJ9R9rBuhr6aJ0w31v+i/CYw4J2RlhpWh",
        "x-amz-request-id": "08E05D2DDE657BF4"
      }
    }
  ]
}
```

eventNameとか見ればS3オブジェクトの追加のされ方がputなのか、copyなのかなどの判別もできるのかなと思います。