今すぐ ALB のアクセスログをクエリする

クックパッドマートでサーバーサイドなどのソフトウェアエンジニアをしている石川です。

この記事では、クックパッドマートとは全然関係なく、私が正社員として新卒入社する前、技術部 SRE グループで就業型インターンをしていた頃に実装したシステムについてご紹介します。

ALB のアクセスログ

弊社では AWS の Elastic Load Balancing (ELB) を多用しており、Application Load Balancer (ALB) が多くのウェブアプリケーションで利用されています。

ところで ALB はアクセスログを Amazon S3保存することができます。このアクセスログにはアクセス先の IP アドレスやリクエスト URL の他、レスポンスのステータスコード、レスポンスまでにかかった時間、User-Agent などの情報が記録されています。

これらの情報は分析の役に立ちます。ロードバランサーは典型的にはユーザーからのアクセスが最初に到達する場所であるため、たとえばエラーとなったアクセスがどこでエラーになったかの調査に ALB のアクセスログが役に立つ場合があります。

また、他にも社内だと以下の用途で ALB のアクセスログが使われたことがありました。

  • 特定のエンドポイントのレスポンスタイム分布の分析
  • 特定の User-Agent を持つリクエスト数の調査
  • 負荷試験のアクセスパターンを作る際の参考データ
  • 非推奨にしたエンドポイントへのアクセス数の調査
  • 499 Client Closed Request の頻度調査

(ただし、ALB のアクセスログはベストエフォートで記録されていることには注意が必要です。ドキュメントにも “We recommend that you use access logs to understand the nature of the requests, not as a complete accounting of all requests.” と書かれています。)

Athena を使ったクエリ

では実際にアクセスログを分析したいとなったとき、どうすれば良いでしょうか。ログが記録されたテキストファイルをダウンロードして手元でスクリプトを実行することでも分析できますが、このようなやり方を毎回繰り返すのは煩わしいですし、素朴な実装だと実行時間もそれなりにかかります。

そこで、ここでは Amazon Athena を使う方法について考えます。Athena は S3 に置かれた大量のデータファイル群に対して SQL で柔軟かつ高速にクエリができるサービスです。S3 に置かれている大量の ALB ログを素早く分析したいという今回のケースにはぴったりです。

実際、AWS のドキュメントには Athena で ALB ログをクエリするためにテーブルを作る SQL のサンプルが書かれています: https://docs.aws.amazon.com/athena/latest/ug/application-load-balancer-logs.html

このようにテーブルを作っておくと、たとえば「GET /users の最近のレスポンスタイムの平均」をクエリしたり「POST /a/deprecated/endpoint に最近目立ったアクセスがあるかどうか」をクエリしたりでき、便利です。具体的には以下のような SQL を書くことになります *1

select
    count(*) as log_count
    , date(from_iso8601_timestamp(logs.time)) as log_date
from
    alb_access_logs.cookpad as logs
where
    date(from_iso8601_timestamp(logs.time)) >= date '2021-09-01'
    and logs.request_verb = 'POST'
    and logs.request_url like '%/a/deprecated/endpoint'
group by 2
order by 2

注意点として、Athena の料金はクエリ時にスキャンされたデータサイズについての従量課金制です。不必要に過去のログすべてに渡ってスキャンすると無駄に課金されてしまいます。クエリにかかる時間を考えても無駄です。

そこでパーティションを利用します。ALB ログが保存されている S3 key には year/month/day が含まれているので、ここについてパーティションを作り、クエリ時に year/month/day について絞り込むことでスキャンサイズを落とすことができます。*2

とはいえ、ALB ログを分析したくなる度にその ALB について Athena でテーブルを作ってパーティションを作って……とするのは面倒です。あらかじめ作ってあった方が便利ですし、日常的な調査をより機敏に行うことができるでしょう。

ということで ALB ログをいつでも Athena で分析できるようにこのあたりを自動化しよう、というのが、私がインターンで取り組んだタスクでした。

テーブルおよびパーティション作成の自動化

さて、それでは自動化いたしましょう。やることは単純で「まだテーブルが作られていない ALB についてテーブルを作り、まだ作られていないパーティションについてパーティションを作る」というバッチを実装すれば良いです *3。今回パーティションは year/month/day 単位で付けようとしているため、実装したバッチは日次で実行すれば良いでしょう。

実装について考えます。テーブル作成部分については Athena で行う方法を先述しましたが、今回のバッチでは Athena の API を使うのではなく、Athena と統合して利用できるAWS Glue の API を使うことにしました。これは、生の SQL を実行することになる Athena よりも「テーブルを作る」などの操作ごとに API が用意されている Glue の方がより細かく権限管理できるためです。また今回の使い方だと Glue の利用にかかる料金は非常に安く、費用面でも問題になりませんでした。

この方針で、テーブル作成とパーティション作成を行ってくれるバッチを Ruby で実装しました。実装するにあたって一番複雑であろう、ログをパースするための正規表現が先述のとおり AWS のドキュメントに掲載されているため、後は AWS SDK を使って実装していくのみでした。このバッチは、社内のバッチ実行基盤である kuroko2 を使って日次で実行されるように設定しました。

このように作成したバッチは私の就業型インターンの期間中に運用が始まり、現在に至るまで特に大きな問題もなく動き続けています。

まとめ

この記事では、ALB のアクセスログを Athena でクエリしやすくするためにバッチを書いた話をご紹介しました。このシステムによって、日々の業務の中でほんの時々必要となるちょっとした作業を減らすことができました。同時に、Athena や Glue にそこまで詳しくなくても SQL がある程度書ければアクセスログをクエリできるという状態を作ることもできました。

このように、インターンの中で現実の問題を解決でき、社内のエンジニアリング環境を少し向上できた、面白いインターンであったと今更ながら考えています。

最後に、クックパッドでは、サービス開発や基盤開発にチャレンジする就業型インターンを通年募集しています。気になった方は是非ウェブサイトよりご応募ください:

info.cookpad.com

*1:すぐ下に書いてあるように、更にパーティションについても絞り込む必要はあります。

*2:更に、ALB ログは 1 行 1 アクセスログで保存されているテキストファイルなので、Parquet などのデータフォーマットに変換することでよりスキャンサイズを落とせる可能性があります。ただし今回は変換にかかる金銭コストと ALB ログへのクエリ頻度を天秤にかけ、この変換までは行っていません。

*3:もっと言うと不要になったテーブルやパーティションを削除しても良いです。

iOSDC Japan 2021 に社員7名が登壇します

こんにちは、モバイル基盤部の茂呂(@slightair)です。 発表される前は何も考えていなかったのに、あたらしい iPad mini の紹介ページを見ていたらちょっと欲しくなってきてしまいました。う〜む。

さて、毎年Appleの新製品やらOSアップデートの一般公開やらワクワクすることが続く季節ですが、ついにやってきましたね! iOSDC Japan 2021 が今週末 9/17(金)〜9/19(日)、オンラインで開催されます!

iosdc.jp

トークのご紹介

クックパッドは、ゴールドスポンサーをさせていただいております。

今回クックパッドからは7名のトークを採択いただき、登壇することになりました! ここで紹介させてください。

Day1

9/18(土) 11:30〜

Track C(40分)

  • 登壇者: あおい / @aomathwift
  • タイトル: 機能ごとに動作するミニアプリでプレビューサイクルを爆速にした話

fortee.jp

Track D(40分)

  • 登壇者: 生井智司 / @ainame
  • タイトル: App Store用スクリーンショットの自動生成をアラビア語対応してSwiftUIで実装してみた

fortee.jp

9/18(土) 13:30〜

Track E(20分)

  • 登壇者: uzzu / @uzzu
  • タイトル: StoreKit のこれまでとこれから

fortee.jp

9/18(土) 17:35〜

Track A(5分)

  • 登壇者: あつや / @n_atmark
  • タイトル: SwiftUI.Textを使いこなす5分間

fortee.jp

Day2

9/19(日) 10:50〜

Track E(20分)

  • 登壇者: yujif / @yujif_
  • タイトル: 自己管理の夢と Screen Time API

fortee.jp

9/19(日) 11:30〜

Track A(40分)

  • 登壇者: giginet / @giginet
  • タイトル: 大規模なアプリのマルチモジュール構成の実践

fortee.jp

9/19(日) 13:30〜

Track B(20分)

  • 登壇者: いまじん / @mrimjn
  • タイトル: MultipeerConnectivityを使った動画のリアルタイム端末間共有 〜料理動画撮影アプリの事例〜

fortee.jp

After Party iOSDC Japan 2021 を開催します!

またiOSDC の開催後、「After Party iOSDC Japan 2021」というイベントをクックパッド主催で 10/1(金)19:00からオンラインにて開催します!

cookpad.connpass.com

このイベントでは、カンファレンスでは惜しくも採択されなかったトーク、発表を終えての裏話、発表には入りきらなかった話などをお話しします。クックパッドのiOS開発ってどうなっているんだろう?どんな社員が働いているんだろう?という疑問のある方、クックパッドに興味のある方、なんかイベントがあるならとりあえず行くぜ!という方がいましたら、ぜひこちらのイベントにもご参加ください。お待ちしております。

※このイベントは「iOSDC Japan 2021実行委員会」が運営するものではありません。

おわりに

カンファレンスには、他にも多くの社員が参加する予定です。トークに関すること、After Party などに関してご質問やご感想などございましたら、お気軽にお声がけください!

クックパッドでは、iOSのサービス開発に一緒に取り組んでくれる仲間を募集しています。トークを見て少しでも興味を持っていただいた方にはこちらをご参照いただけましたら幸いです。

info.cookpad.com

それでは、カンファレンスでお会いしましょう!

Cookpad Summer Internship 2021 10 Day Techコースを開催しました!

f:id:fufufukakaka:20210426121451j:plain

研究開発部の深澤(@fukkaa1225)です。今年はエンジニアの立場から新卒採用も担当しています。

4月の記事で告知したサマーインターンシップのうち、10 Day Techコースを8月16日〜8月27日で開催しました。この記事ではその内容を紹介します。

3 Day Product Designコースについては、以下の記事をご覧ください。

10 Day Techコースは、前半5日間が講義形式、後半5日間が実践形式でした。 前半は技術講義とサービス開発講義の2本立てです。 後半はOJTプログラムとPBL(Project-Based Learning)プログラムのそれぞれに分かれて、サービス開発の実践に取り組みます。

昨年はオンラインのみでの開催でした。今年は前半の講義パートをオンラインのみ、後半の実践パートではオフィスに来訪されることを希望した方にはオフィスで、それ以外の方々は前半から引き続きオンラインで参加する形式を取りました。例年と同様、多くの学生の方々にご参加いただきました。本当にありがとうございました。

前半

まずは前半の講義について簡単にご紹介致します。

1日目: フロントエンド講義

初日は1時間弱ほど、イントロダクションとしてクックパッドの取り組みの紹介や自己紹介を行いました。

その後、今年の技術講義のテーマを発表しました。今年のテーマは「ミニクックパッドマートを作る」でした。クックパッドマートを題材として、クックパッドの中で使われている技術スタックを一気に学習・実践することが狙いでした。

イントロダクションを終えた後、フロントエンド講義からいよいよ技術講義がスタートしました。 2021年の春インターンでも用いた動画を見るという事前準備を前提として、午前中の1時間でクライアントサイドから見たGraphQLに関する講義を行いました。

その後、午後はミニクックパッドマートのweb画面を作ることを目標として、基礎課題・発展課題に取り組みました。

2日目: iOS講義

2日目のiOS講義は1日目に実装したミニクックパッドマートの画面を、SwiftUIで実装するという内容でした。iOS未経験の方がほとんどで、環境構築のところが難所ではあったものの、 SwiftUIを実際に触ってみて使いやすいと感じた人が多かったようです。ほとんどの人が基礎課題を完了させるところまで実装を完了させていました。

3日目: サーバサイド講義

3日目はサーバサイド講義でした。例年の講義では、APIを前半に自分たちで作ってから、その自作APIを使って後半の講義で画面を作るという流れでした。しかし、各自の進捗度合いなどによって想定仕様と微妙に異なる自作APIとなってしまい、画面を作る際に苦労してしまうことがありました。

これを踏まえて、今年はあらかじめ完成しているAPIサーバをこちらで立てて、前半に画面を作る講義を配置してAPIの仕様を把握しながら画面を作りました。その後、3日目のサーバサイド講義で、これまで使ってきたAPIを自分たちで実装してみる、という流れをとりました。

実際に作成してみるのは、GraphQLのAPIサーバです。これをRubyで実装する講義でした。また、決済を担当する別サービス(minifinancier)とのサービス間通信をgRPCで実装するなど、発展的な内容も多く盛り込まれた講義でした。非常にボリュームの多い内容で、多くの方々が苦労されていましたが、それでも何とか乗り切っていました。

4日目: インフラ講義

4日目のインフラ講義では、クックパッドにおけるSREが果たしている役割とその歴史を、実例を交えつつ紹介しました。演習パートでは、基礎課題としてTerraform・hakoを用いて、ミニクックパッドマートをデプロイした他、minifinancierをデプロイしてgRPCのサービス間通信を張る、発展課題として静的ファイルをS3+Cloudfront構成で配信するなどの課題に取り組みました。

スライド: https://static.cookpad.com/techlife/cookpad_summer_internship_2021_infra/main.pdf

補助資料

5日目: サービス開発講義

前半最終日はサービス開発講義を実施しました。午前はクックパッドのサービス開発に対する考え方や開発プロセスを座学形式で学びました。 午後は、午前で学んだことをベースにインターン生同士でチームを組み、ZoomやFigmaを活用したオンラインでのグループワークを行いました。グループワークでは、与えられたテーマを元にユーザーインタビューや価値仮説、アイデア出し、プロトタイプの作成までを一貫して実践しました。講義の終盤では実際に作成したプロトタイプをユーザーにテストしてもらい、それら結果をまとめて各チームでの成果発表を行いました。

「丸1日コードを書かない講義です」とアナウンスしたときからどんな講義なんだろう?と皆さん気になっていたようでした。実際に取り組んでみて、サービス開発について体系的に学び実践する機会がなかなかないので、貴重な良い経験ができたと好評でした。

後半

後半はPBLコースとOJTコースそれぞれに分かれての実践パートでした。

f:id:fufufukakaka:20210906103359j:plain
講師との壁打ちの様子

f:id:fufufukakaka:20210906104529j:plain
雑談していた様子

PBLでは前週のサービス開発講義の内容を元にして、サービス開発の実習を行いました。「一人暮らしの料理」に関する課題を見出し、それを解決するアプリケーションを提案、実装・デプロイしきる、という工程を5日間という短い時間でやりきるというタイトなものでした。 仮説検証、実装時の技術相談などを社員がサポートしつつ着実に進めていった結果、最終的にはほぼ全員がデプロイまでやりきり、無事に成果を発表できていました。

f:id:fufufukakaka:20210906103047j:plain
PBL成果発表の様子、 撮影:WeWork Oceangate Minatomirai

最終講評はCTOの成田、レシピ事業部部長など4名が成果物を真剣に審査しました。実際にそれで課題を解決することができているのか、技術力をどれだけアピールできているか、など複数の視点から評価を行いました。

f:id:fufufukakaka:20210906102845j:plain
講評者のCTO成田、 撮影:WeWork Oceangate Minatomirai

厳正なる審査の結果、技術観点・サービス観点から優秀だった方にはそれぞれ賞を贈らせていただきました。どちらもそれぞれ、特別な賞品を贈呈いたしました。

OJTではクックパッドの各部署に配属され、メンターの指導を受けながらサービス開発を実践してもらいました。レシピサービス、クックパッドマート、基盤系の部署などさまざまな部署に配属された後、みなさんそれぞれのタスクをやり遂げていただきました。 最終日にはPBLコースと合わせて、各自が取り組んだタスクを発表してもらいました。ほとんど全員がPRのマージ、本番環境へのデプロイまでこなしており、発表を聞いていた人全員がみなさんの偉業に驚いていました。

f:id:fufufukakaka:20210906115758j:plain
OJT成果発表の様子、 撮影:WeWork Oceangate Minatomirai

インターンシップを終えて

簡単にではありますが、10日間のサマーインターンシップを振り返させていただきました。 昨年はすべてオンラインでの開催でしたが、今年は後半の実践プログラムについてオンラインとオフィスを選択希望制にしました。昨今の情勢もあり全員にご来訪いただくことは叶わない難しい状況でしたが、恵比寿からみなとみらいに移転した新しいオフィスを、参加者の方々に体感いただく機会を設けられて良かったと感じています。 全体を通じてリモート中心の設計という点は昨年と同様であったため、Zoom、Slack、Kibelaを最大限に活用しました。また、これまでの取り組みを踏まえて、より一層双方向のコミュニケーションを意識しました。具体的にはSlackでpollやreactionによる双方向的でカジュアルなコミュニケーションを織り交ぜたり、Zoom上でブレイクアウトルームを活用したチームごとの成果発表やワークを取り入れる講義などがありました。 今回得られた知見を、次回以降の取り組みにも活かしていきたいと思います。

ノベルティ

f:id:fufufukakaka:20210906103238j:plain
ノベルティセット

f:id:fufufukakaka:20210906103300j:plain

f:id:fufufukakaka:20210906103327j:plain
オフィス招待カード

写真のノベルティセット(アメ、ラムネ、スマートフォンスタンド、マルシェバッグ、うちわ、ステッカー)を事前に送付しました。 また、全日リモート参加を選択された方には、別の機会で改めてオフィス見学に来ていただけるように、オフィス招待カードも送付させていただきました。 この他にサマーインターンシップのロゴが入ったZoomのバーチャル背景用の画像も配布しています。

まとめ

以上が、Cookpad Summer Internship 2021 10 Day Techコースの開催報告です。 ご参加いただいた皆さま、本当にありがとうございました!

今年のサマーインターンシップは終わってしまいましたが、クックパッドでは就業型インターンシップを通年で募集しています。 興味のある方はぜひご応募ください!

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('https://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/