SlideShare a Scribd company logo
2013/04/19
株式会社FLECT
小西俊司
@shunjikonishi
 PapertrailのアーカイブしたログをS3から取ってきてなんとなく解析
 ライブサンプル(http://flect-
papertrail.herokuapp.com/loganalyzer)
 ソース(https://github.com/shunjikonishi/papertrail-log-analyze)
 PapertrailがS3に転送したアーカイブログを取得してログの行数やログ
内の数値(レスポンスタイムなど)を数えまくる
 カレンダーで日付をクリックするとその日のログを解析
◦ 解析結果はS3に書き戻し
 解析結果は1時間毎に区切ってテーブル表示
 選択行をグラフ表示
 解析結果と生ログのダウンロード
 カウントする項目はなんとなく設定可能
◦ 設定項目もS3に保存
 NewRelicやGoogleAnalysticと違い事後のログ解析なのでアプリへの
影響は全くない
 ソースをcloneしてHerokuにpushすればAddOn一切なしで使用可能
(無料)
◦ Herokuでアプリを作ってて
◦ PapertrailでログをS3にアーカイブ
◦ してないとまったく意味がない
 実案件のログ解析のため
 負荷テストのお供
◦ 思った以上に使える
 社内で実施する予定のAjaxアプリケーション勉強
会のネタ
◦ なのでJavaScriptのコードは普段よりもかなり丁寧に書
いた
◦ しかしUIは割と適当
◦ 国際化もネタの一つなので英語リソースもあり(超適当)
 Play2(Scala)でなんか作ってみたかった
 なんか数えられるものは何でも数えてしまう病気
かも。。。(--
 HerokuにpushしてPapertrailのログがアーカイブ
されているS3の情報を設定
 「PAPERTRAIL_ARCHIVE_xxxx」は複数設定可
 TIMEZONEを「Asia/Tokyo」にすることで時刻の
表示が日本時間になる。(デフォルトUTC)
git clone git@github.com:shunjikonishi/papertrail-log-analyze.git
heroku create
git push heroku master
heroku config:add S3_ACCESSKEY=<your aws accessKey>
heroku config:add S3_SECRETKEY=<your aws secretKey>
heroku config:add PAPERTRAIL_ARCHIVE_APP1=<your S3 bucket>/papertrail/logs
heroku config:add TIMEZONE=Asia/Tokyo
 ALLOWED_IPをすると指定のIPからしかアクセスできなく
なる
◦ IPv4形式。カンマ区切りで複数設定可
 BASIC_AUTHENTICATIONを指定するとBasic認証がかか
る
◦ ユーザー名とパスワードの「:」区切り
 PASSPHRASEを指定すると設定変更と生ログダウンロード
の際にパスフレーズの入力が要求される
◦ 任意の文字列
◦ ちなみに日本語を設定するとアプリがクラッシュする上に
heroku configやheroku releases:rollbackもエラーとなって自
分で回復させることができずサポートのお世話になる羽目になる
(--
heroku config:add ALLOWED_IP=xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy,zzz.zzz.zzz.zzz/24
heroku config:add BASIC_AUTHENTICATION=username:password
heroku config:add PASSPHRASE=xxxxxxx
 ログの数え方は大きく分けて以下の二つ
 ログ件数
- 条件にマッチする行の
◦ 一時間毎の件数
◦ その時間帯での1分間の出力数の最大値
◦ その時間帯での1秒間の出力数の最大値
 ログ内の数値の最大値と平均値
– 条件にマッチする行から数値を抜き出して
◦ 一時間毎の件数
◦ その時間帯での最大値
◦ その時間帯での平均値
 Play 2.1(Scala) on 1 Dyno
◦ ていうかこのアプリだ
 テスト対象のページはほぼ静的なページ
◦ サーバーサイドでリクエストハンドラの先頭から最後ま
での時間を計測すると平均1ms以下
 15時台に100スレッド × 100回のリクエスト実行
 16時台に500スレッド × 100回のリクエスト実行
 17時台に1000スレッド × 100回のリクエスト実
行
◦ しかし、Jmeterが途中で固まった
 19時台に1000スレッド × 100回のリクエスト実
行
◦ 今度は最後まで実行できた
 Herokuと自前アプリの出力しているログの全行
 自分以外誰も使っていないのでテストしている時間帯
以外はまったくログがでていない
 リクエストハンドラ内でログ出力しているのでログの
総件数としてはアクセス数の2倍になる
 ちなみにPostgreSQLがいるとやたらログの行数が増
える
 Herokuの出力するアクセスログ
(program=heroku/router)
 すべてのログとまるっきり同じに見えるけど良く
見るとY軸の数字が半分になっている
 アクセスログのうち「service=xxms」の部分が指定時間以上
のログの件数
 負荷指標のひとつ
 100スレッド、500スレッドは余裕でさばいているように見える
◦ というかDBアクセスがないのでサーバー側の処理はほとんどなく、処理
が始まってしまえば一瞬で終わるのは当たり前(テストケースがよろしく
ない)
◦ 19時台のテストで数字が跳ね上がっているのはフレームワーク(Play2)の
どこかがボトルネックになっていると推測
 アクセスログの「service=XXms」の部分の件数、平均、最大値
 最大値はいろいろな要因で極端に大きくなることがあるのであまり当てにならな
い
 平均値は500スレッドまではまずまず。
◦ ただしネットワークレイテンシがあるのでクライアント側で計測した数字とは1000ms近い
差がある
 100スレッドのテストが遅いのはおそらくサーバー起動直後だったため
レスポンスタイムはパス毎に集計
設定で正規表現で複数のパスをま
とめることもできる
例)商品詳細画面をまとめる
商品詳細=/product/(d)+
 アクセスログのうち「connect=XXms」の部分が指
定時間を以上のログの件数
 負荷のない状態ではほぼ5ms以下なので20msはかな
り遅い
 この数字が大きくなるようならDynoを増やした方が
良いかも
 アクセスログのうち「connect=XXms」の部分の件数、平均、
最大値
 クライアントから見た体感速度は
◦ レスポンスタイム+接続時間+ネットワークレイテンシとなるはず
◦ USまでのネットワークレイテンシは経験的には負荷のない状態で
100ms前後
 500スレッドでも若干遅いが多分Dynoを増やせば解決するはず
 サーバーエラー(50x)
◦ アクセスログのうち「status=xxx」の部分が50xのログの件
数
◦ 自分で意図的に50xを返しているのでなければ多分バグ
◦ あるいはHeroku側で50xを返す場合もある
 タイムアウト(アプリが30秒以内にレスポンスを返さない)
 接続エラー
 これらの場合Herokuのエラーコードがでるので別にカウント可能
 クライアントエラー(40x)
◦ アクセスログのうち「status=xxx」の部分が40xのログの件
数
◦ Faviconとかスマホ用のホームアイコンとかをちゃんと用意し
ておかないとやたらとたくさんでる
◦ 攻撃も結構ある
 Herokuエラー別
◦ Herokuのエラーコード毎の集計
◦ 多分全部取れていると思うけど漏れているものもあるかも
◦ Hxxはネットワークエラーなので日に数回でるのは仕方がな
い。(クライアントから接続を切った場合などにもでる)
◦ R14(メモリ使いすぎ)はもう見飽きた
 プログラム別
◦ プログラム毎の集計
◦ App/xxxはユーザーアプリのログ
 複数のWebDynoがある場合にはリクエストがほぼ均等に割り振ら
れているのがわかる
◦ Heroku/xxxはHerokuの出しているログ
 PostgreSQLログ出しすぎ
 Dynoステート変更
◦ Herokuログのうちメッセージが「State changed」で始まる
ログの件数
◦ Dailyの再起動とか、Git push、環境変数変更で発生
 Dyno起動時間
◦ 「State changed … to starting」のログから「State
changed … to up」までのログの時間
◦ 秒単位(Papertrailのログのタイムスタンプが秒までしかでて
いないため)
 Herokuのログタイムスタンプは最近マイクロ秒まで出るように
なったがPapertrailは対応していない
◦ 10秒くらいだと思っていたら平均20秒ちかくかかっていて憂
鬱になった(--
 Dailyの再起動がこれまでは複数Dynoある場合でも同時に行われ
ていたのが、時間をずらして行われるようになっている気がする
のでそうであれば起動時間は気にする必要がないとは思う
 HerokuPostgresでは
「log_min_duration_statement=50ms」が設定されて
いるため50ms以上かかったSQLの実行はすべてログに出
力される
◦ 50msはかなり短いと思う
◦ SQL実行はマシンパワーにかなり依存するので非力なDBを使って
いると無茶苦茶いっぱい出る
 そこで出力される時間の件数、平均値、最大値をSQL毎に
出力
◦ SQL文中のリテラルやIN句は適当に置換しているのでそこそこい
い感じにまとまるはず
◦ あくまで50ms以上かかったSQLの平均なので全SQLの平均では
ない
 COPYステートメントも出力されるのでpgbackupが動い
ているとその時間だけ数値が跳ね上がる
◦ Pgbackupは動く時間を指定させてほしい。。。
 正規表現カウント
◦ 「名前=正規表現」の形式で設定してその件数をカウン
ト
◦ 例えば「バグっぽい=UnexpectedError」みたいな
◦ 「ログイン=Login.* Username=(.+)」のようにグルー
プを指定するとグループ毎に件数をカウントする
 正規表現数値
◦ 「名前=グループのある正規表現」の形式で設定してそ
のグループ部分の数値の件数、平均値、最大値をカウン
ト
◦ 例えば「検索時間=Search.*: (d+)ms」みたいな
 とりあえずHerokuに特化しているけど、Apache用の
アクセスカウンターなども割と簡単に作れるので必要
に迫られればやる
 アクセスログ解析はHerokuのログフォーマットに依
存しているが、最近LabeledSeparatedな形式に変
わったので項目が増えることはあっても形式が変わる
ことはないんじゃないか(楽観)
 どっちかというとPapertrailへの依存度の方がリスク
高い
◦ アーカイブのTSVフォーマット
◦ ディレクトリ構成
◦ ファイル名フォーマット
などが変わるとあっさり動かなくなる
 去年の夏頃(2.0.2)に比べてものすごく使いやすくなってい
る
 しかしまだ足りない機能も多い
◦ セッションIDがないのはかなり愕然とした
◦ MemcachedもHerokuでは必須になるが外部プラグイン
 DBは今回触ってないので評価保留
 2.0.2の頃はファイルアップロードまわりのハンドリング
がいけてなかった記憶があるがそれもやってないので評価
保留
 コード量はおそらくjavaの3分の1以下
◦ Scala素晴らしすぎる(変態言語だが)
 PluginのエントリポイントがOnStart/OnStopしかないよ
うに見えるが。。。?
◦ HTTPリクエストの前後にバインドできればたいていのことは自
力でなんとかできそうなので実案件にも適用できるかも
◦ ていうかセッションIDがないのはあまりにも致命的なのでまずは
セッションプラグインを作りたい(--

More Related Content

Viewers also liked

カスタムアプリケーションプラットフォーム Salesforce Heroku ~ ソーシャルアプリケーションを支える技術 ~
カスタムアプリケーションプラットフォーム Salesforce Heroku~ ソーシャルアプリケーションを支える技術 ~カスタムアプリケーションプラットフォーム Salesforce Heroku~ ソーシャルアプリケーションを支える技術 ~
カスタムアプリケーションプラットフォーム Salesforce Heroku ~ ソーシャルアプリケーションを支える技術 ~Ayumu Aizawa
 
Javascriptのあれやこれやをまとめて説明してみる
Javascriptのあれやこれやをまとめて説明してみるJavascriptのあれやこれやをまとめて説明してみる
Javascriptのあれやこれやをまとめて説明してみるShunji Konishi
 
Ruby on railsでlinebotを試した記録
Ruby on railsでlinebotを試した記録Ruby on railsでlinebotを試した記録
Ruby on railsでlinebotを試した記録
Fumiya Sakai
 
ソーシャルゲームログ解析基盤のMongoDB活用事例
ソーシャルゲームログ解析基盤のMongoDB活用事例ソーシャルゲームログ解析基盤のMongoDB活用事例
ソーシャルゲームログ解析基盤のMongoDB活用事例
知教 本間
 
Hadoopを用いた大規模ログ解析
Hadoopを用いた大規模ログ解析Hadoopを用いた大規模ログ解析
Hadoopを用いた大規模ログ解析
shuichi iida
 
Salesforce連携のためのOData入門
Salesforce連携のためのOData入門Salesforce連携のためのOData入門
Salesforce連携のためのOData入門
Shunji Konishi
 
現在のDNNにおける未解決問題
現在のDNNにおける未解決問題現在のDNNにおける未解決問題
現在のDNNにおける未解決問題
Daisuke Okanohara
 
IIBMP2016 深層生成モデルによる表現学習
IIBMP2016 深層生成モデルによる表現学習IIBMP2016 深層生成モデルによる表現学習
IIBMP2016 深層生成モデルによる表現学習
Preferred Networks
 

Viewers also liked (8)

カスタムアプリケーションプラットフォーム Salesforce Heroku ~ ソーシャルアプリケーションを支える技術 ~
カスタムアプリケーションプラットフォーム Salesforce Heroku~ ソーシャルアプリケーションを支える技術 ~カスタムアプリケーションプラットフォーム Salesforce Heroku~ ソーシャルアプリケーションを支える技術 ~
カスタムアプリケーションプラットフォーム Salesforce Heroku ~ ソーシャルアプリケーションを支える技術 ~
 
Javascriptのあれやこれやをまとめて説明してみる
Javascriptのあれやこれやをまとめて説明してみるJavascriptのあれやこれやをまとめて説明してみる
Javascriptのあれやこれやをまとめて説明してみる
 
Ruby on railsでlinebotを試した記録
Ruby on railsでlinebotを試した記録Ruby on railsでlinebotを試した記録
Ruby on railsでlinebotを試した記録
 
ソーシャルゲームログ解析基盤のMongoDB活用事例
ソーシャルゲームログ解析基盤のMongoDB活用事例ソーシャルゲームログ解析基盤のMongoDB活用事例
ソーシャルゲームログ解析基盤のMongoDB活用事例
 
Hadoopを用いた大規模ログ解析
Hadoopを用いた大規模ログ解析Hadoopを用いた大規模ログ解析
Hadoopを用いた大規模ログ解析
 
Salesforce連携のためのOData入門
Salesforce連携のためのOData入門Salesforce連携のためのOData入門
Salesforce連携のためのOData入門
 
現在のDNNにおける未解決問題
現在のDNNにおける未解決問題現在のDNNにおける未解決問題
現在のDNNにおける未解決問題
 
IIBMP2016 深層生成モデルによる表現学習
IIBMP2016 深層生成モデルによる表現学習IIBMP2016 深層生成モデルによる表現学習
IIBMP2016 深層生成モデルによる表現学習
 

More from Shunji Konishi

SendGridサンプルの紹介
SendGridサンプルの紹介SendGridサンプルの紹介
SendGridサンプルの紹介
Shunji Konishi
 
セキュリティの考え方
セキュリティの考え方セキュリティの考え方
セキュリティの考え方
Shunji Konishi
 
一番簡単なWebSocketの試し方
一番簡単なWebSocketの試し方一番簡単なWebSocketの試し方
一番簡単なWebSocketの試し方
Shunji Konishi
 
WebSocketでリアルタイムクイズアプリを作ってみた
WebSocketでリアルタイムクイズアプリを作ってみたWebSocketでリアルタイムクイズアプリを作ってみた
WebSocketでリアルタイムクイズアプリを作ってみたShunji Konishi
 
良質なコードを高速に書くコツ
良質なコードを高速に書くコツ良質なコードを高速に書くコツ
良質なコードを高速に書くコツ
Shunji Konishi
 
Heroku tips1
Heroku tips1Heroku tips1
Heroku tips1
Shunji Konishi
 
Playframework1でSeleniumテスト
Playframework1でSeleniumテストPlayframework1でSeleniumテスト
Playframework1でSeleniumテスト
Shunji Konishi
 
Heroku Dyno再起動時の振る舞い
Heroku Dyno再起動時の振る舞いHeroku Dyno再起動時の振る舞い
Heroku Dyno再起動時の振る舞い
Shunji Konishi
 
Dyno cycling behavior of Heroku
Dyno cycling behavior of HerokuDyno cycling behavior of Heroku
Dyno cycling behavior of HerokuShunji Konishi
 
Herokuで使えるRDBMS管理者ツール
Herokuで使えるRDBMS管理者ツールHerokuで使えるRDBMS管理者ツール
Herokuで使えるRDBMS管理者ツールShunji Konishi
 
お手軽Ajaxアプリケーションの作り方
お手軽Ajaxアプリケーションの作り方お手軽Ajaxアプリケーションの作り方
お手軽Ajaxアプリケーションの作り方
Shunji Konishi
 
Excel2 canvas
Excel2 canvasExcel2 canvas
Excel2 canvas
Shunji Konishi
 
特盛!Heroku
特盛!Heroku特盛!Heroku
特盛!Heroku
Shunji Konishi
 
文字コードのお話
文字コードのお話文字コードのお話
文字コードのお話
Shunji Konishi
 
High traffic questionnaire site
High traffic questionnaire siteHigh traffic questionnaire site
High traffic questionnaire site
Shunji Konishi
 

More from Shunji Konishi (16)

SendGridサンプルの紹介
SendGridサンプルの紹介SendGridサンプルの紹介
SendGridサンプルの紹介
 
セキュリティの考え方
セキュリティの考え方セキュリティの考え方
セキュリティの考え方
 
一番簡単なWebSocketの試し方
一番簡単なWebSocketの試し方一番簡単なWebSocketの試し方
一番簡単なWebSocketの試し方
 
WebSocketでリアルタイムクイズアプリを作ってみた
WebSocketでリアルタイムクイズアプリを作ってみたWebSocketでリアルタイムクイズアプリを作ってみた
WebSocketでリアルタイムクイズアプリを作ってみた
 
良質なコードを高速に書くコツ
良質なコードを高速に書くコツ良質なコードを高速に書くコツ
良質なコードを高速に書くコツ
 
Heroku tips1
Heroku tips1Heroku tips1
Heroku tips1
 
Playframework1でSeleniumテスト
Playframework1でSeleniumテストPlayframework1でSeleniumテスト
Playframework1でSeleniumテスト
 
Heroku Dyno再起動時の振る舞い
Heroku Dyno再起動時の振る舞いHeroku Dyno再起動時の振る舞い
Heroku Dyno再起動時の振る舞い
 
Dyno cycling behavior of Heroku
Dyno cycling behavior of HerokuDyno cycling behavior of Heroku
Dyno cycling behavior of Heroku
 
Herokuで使えるRDBMS管理者ツール
Herokuで使えるRDBMS管理者ツールHerokuで使えるRDBMS管理者ツール
Herokuで使えるRDBMS管理者ツール
 
Play1 to Play2
Play1 to Play2Play1 to Play2
Play1 to Play2
 
お手軽Ajaxアプリケーションの作り方
お手軽Ajaxアプリケーションの作り方お手軽Ajaxアプリケーションの作り方
お手軽Ajaxアプリケーションの作り方
 
Excel2 canvas
Excel2 canvasExcel2 canvas
Excel2 canvas
 
特盛!Heroku
特盛!Heroku特盛!Heroku
特盛!Heroku
 
文字コードのお話
文字コードのお話文字コードのお話
文字コードのお話
 
High traffic questionnaire site
High traffic questionnaire siteHigh traffic questionnaire site
High traffic questionnaire site
 

Herokuのログ解析ツール