Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Jawsug福岡 201606 up

1,727 views

Published on

JAWS-UG福岡での発表資料です。
別名「月額10円から作るServerLess Website ガラケー版」

Published in: Technology
  • Be the first to comment

Jawsug福岡 201606 up

  1. 1. Lambdaで始めるlog-driven サービス構築 2016年6月11日 木村健一郎
  2. 2. 名前:木村健一郎 所属:株式会社コム・アンド・コム お仕事:技術に関することはなんでも 好きな言語:perl 好きなDB:PostgreSQL
  3. 3. 今日のお題: Lambdaでlog-drivenなサービスを作る
  4. 4. Log-driven? • 私が思いついた言葉なのでググらないように • Log-driven developmentなんてこと言ってる人はいる みたいですが、読んでません • リクエストに対して直接アクションするのではなく、出 力されたログに基づいてアクションするアーキテクチャ • ログは取らないわけないよね?ならそれを中心にし てしまいましょう • ログをリクエストバッファに使うイメージといえば いいんでしょうか ・・・どういう需要があるの?
  5. 5. ところで みなさん、前回の森田さんの発表(月額10円から作る ServerLess Website)、憶えてますか?
  6. 6. 超ざっくり言うと、 ・S3にstatic HTMLとjs置いて、お問い合わせの入力を受ける ・入力はjsからS3に保存される ・保存されたらLambdaが拾ってアクションする (※)もっと沢山の素晴らしいアイデアが含まれてるので、是非発表 資料をご覧になってください
  7. 7. 私:「js動かない ガラケーはどうしましょ?」 森田さん:「あきらめましょう」(要約) ・・・・(´・ω・`)
  8. 8. 何かやりようがあるのでは? 寝ないで3日考えた(嘘) 入力を全部GETで渡してログを解析すれば いいんじゃね?
  9. 9. 想定動作 • 名前とメールアドレス、問い合わせ内容を受け付ける • 入力したら完了ページを出す • 入力された内容をSlackで通知する • アクションは何でもいいんですが、前回のコードを 使い回してるのでslackへ飛ばしてます • ガラケーでもw3mでもlynxでも動くこと
  10. 10. 構成(レガシー) インターネットhttpアクセス S3 FluentdでログをS3に保存 GET /result.php?body=hogehogehoge Slackに通知 入力を受け付 け、Slackに流 すWEBアプリ
  11. 11. 今回の構成 インターネットhttpアクセス S3 ログをS3に保存 イベント通知 ログ読み込み GET /result.html?body=hogehogehoge Slackに通知
  12. 12. S3の設定(1) S3でstatic HTMLサーバを作ります。HTMLは以下のような感じで。 <HTML> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> </head> <body> お問い合わせはこちらからどうぞ。<BR> <FORM action="result.html" method="GET"> メールアドレス:<INPUT type="text" name="from"><BR> お名前:<INPUT type="text" name="lname"><BR> 本文:<BR> <TEXTAREA name="body" rows="10" cols="40"></TEXTAREA> <BR> <INPUT type="submit" value="送信"> </FORM> </BODY> </HTML> <HTML> <head> <meta http-equiv="content-type" content="text/html;charset=shift_jis"> </head> <body> お問い合わせありがとうございました。<BR> 追って担当より御連絡申し上げます。<BR> </BODY> </HTML> input.html result.html
  13. 13. S3の設定(2) ログ用のバケットを作成して、ログを設定します。
  14. 14. Lambda Functionを書きます。ログのパースにapachelogモジュールを、そこからクエリーパラメータをパースするのにurlparseを 使います。まずはs3からオブジェクト読み込んで、ログ解析用のフォーマットを設定。 Lambdaファンクション # coding: utf-8 import boto3 import json import sys import ConfigParser import urlparse import apachelog import slackweb import re def lambda_handler(event, context): record = event["Records"][0] bucket_region = record["awsRegion"] bucket_name = record["s3"]["bucket"]["name"] log_object_key = record["s3"]["object"]["key"] s3 = boto3.client('s3', region_name=bucket_region) logobj = s3.get_object(Bucket = bucket_name, Key = log_object_key) try: log = logobj["Body"].read().decode('utf-8'); except: log = '' fname = 'result.html' format = r'%{id} %{backetname} %t %h %x %{uid} %{action} %f "%r" %>S %{z} %{a} %{b} %{c} %{d} "%{Referer}i" "%{User- Agent}i" %y' al = apachelog.parser(format)
  15. 15. S3オブジェクトから1行ずつ取り出して、対象のWEBアクセスであれば解析してSlackに飛ばします。 Lambdaの設定(2) for line in log.split('n'): try: ldata = al.parse(line) if ldata['%{action}'] == 'WEBSITE.GET.OBJECT' and ldata['%f'] == fname: url = re.sub('^GET /(.*) HTTP/1..$',r"1",ldata['%r'],re.U) o = urlparse.parse_qs(urlparse.urlparse(url).query) from = o['from'][0].decode('shift_jis') lname = o['lname'][0].decode('shift_jis') body = o['body'][0].decode('shift_jis') inifile = ConfigParser.SafeConfigParser() inifile.read("./config.ini") attachments = [] attachment = { "fallback": u"From:%sn%s" % (lname,body), "pretext": u"From:%snSub:%s" % (lname,from), "color": "#aaaaaa", "text": body } attachments.append(attachment) slack = slackweb.Slack(url=inifile.get('slack', 'hook_url')) slack.notify(attachments=attachments, channel=inifile.get('slack', 'channel'), username=inifile.get('slack', 'username'), icon_emoji=inifile.get('slack', 'icon_emoji'))
  16. 16. tryのキャッチと関数からのreturn。 Lambdaの設定(3) except: print(line) return "CONTINUE"
  17. 17. 制限はあります • s3へのログの書き込みがリアルタイムでない •大体30分~1時間かかる •バッチ処理で十分な案件には使える • URLの長さの上限がある •IEは2MB?ガラケーはもっと小さいはず • URLでダダ漏れなので、機密情報は入れないように
  18. 18. 使い道はありそう • ちょっとしたデータを受け付けるCGIのためだけにEC2を動 かさないでいい • 無記名アンケートなんかはいいかも? • 「完了ページに入力内容を出したい」なんてことは出来な い • その程度ならSSIでいけるからEC2でWEBサーバ作るに しても超軽量でOK
  19. 19. 注意とお詫び このコードだと日本語がどうしても通りませんでした・・ • ローカルでは動くので、urlparseのバージョンの問題?(´・ω・`) • たぶんUTF8なら動くけど、それじゃガラケーが動かないし・・ • Python3ならparse_qsにencodingってパラメータがあるんですけどね。 • Javaで書いたらもっと楽な気がした
  20. 20. 応用 これで終わったらさみしいので、応用を考えてみた。 • ログをS3に書けばいいんだから、fluentdと組み合わせる • swatchの代わりにlambdaを使う • アクセスログに基づいてWAFやVPCのACLに設定を突っ 込む • Apacheのmod_dosdetectorみたいなこととか
  21. 21. 感想 • やっぱりLambda超便利(^o^) • 頑張ればガラケー向けの問い合わせページもサーバレスで 作れます!(`・ω・´) • 「バッチのためのEC2をLambda置き換える」と同じ発想で 色々応用できそう • ログをトリガーにlambda(じゃなくてもいいけど)で色々や ることを「log-drivenサービスアーキテクチャ」と名前つけ たらかっこよくない?

×