読者です 読者をやめる 読者になる 読者になる

bauer's diary

凡人の凡人による凡人のための備忘録

ghq/peco/hubを組み合わせてローカル・リモートリポジトリに即座にたどり着く

はじめに

あまりにも有名な下記ツールを組み合わせて、ストレスなく、リポジトリにたどり着くような設定にしたのでまとめておきます。

あまりにも有名なので、ツールの説明は割愛します。が、ざっくりいうと、

Go製のリポジトリ管理ツール
github.com
同じくGo製の使い勝手のいいフィルタリングツール
github.com
GitHubCLIで操作するツール
github.com
ですw

ローカル編

ローカルにcloneしたリポジトリを一覧して選択したリポジトリに移動する 操作を素早く行えるようにしています。
zshだとこんな感じの設定になります。

function peco-src () {
  local selected_dir=$(ghq list -p | peco --query "$LBUFFER")
  if [ -n "$selected_dir" ]; then
    BUFFER="cd ${selected_dir}"
    # pecoで選択中, Enter を押した瞬間に実行する
    zle accept-line
  fi
  zle clear-screen
}
# 関数をウィジェットに登録
zle -N peco-src
bindkey '^]' peco-src

"ghq list -p" で、"ghq get"でローカルにクローンしたリポジトリ一覧を表示します。
パイプでつないだ'peco --query "$LBUFFER"'で、その一覧をpecoのコンソールに表示させます。
このようなやり方は、他のQiitaの記事でも紹介されている(というかほぼパクリ)ので、目新しいことはありません。

リモート編

リモートリポジトリを一覧し、選択したリポジトリをブラウザで表示します。
下記は、先程のローカル用の関数をカスタマイズして作成した関数です。

function peco-src-remote () {
  local selected_repo=$(ghq list -p | peco --query "$LBUFFER" | rev | cut -d "/" -f -2 | rev)
  echo $selected_repo
  if [ -n "$selected_repo" ]; then
    BUFFER="hub browse ${selected_repo}"
    zle accept-line
  fi
  zle clear-screen
}
zle -N peco-src-remote
bindkey '^^' peco-src-remote
解説

hubツールに"browse"というコマンドを使って、リモートのリポジトリページをブラウザで開くことができます。

$ hub browse [ユーザ名/リポジトリ名]

なので、下記のようなローカルリポジトリのパス文字列を分解して"hub browse"に渡すということをしたいとおもいます。

$ /Users/kitakitabauer/.ghq/github.com/ユーザ名/リポジトリ名

しかし、$GOPATHやghqのルートによって、パス階層がどのぐらいになるのかわからないので、渡す文字列を固定で切り出すことがめんどくさそうです。

  • /Users/kitakitabauer/.ghq/github.com/kitakitabauer/dotfiles
  • /Users/kitakitabauer/go/src/github.com/kitakitabauer/dotfiles
  • /Users/kitakitabauer/go/src/bitbucket.org/kitakitabauer/dotfiles

自分は以前の記事でご紹介しましたが、".ghq" や "go/src" のように、cloneするディレクトリを分けているので、単純に前者と後者で階層に1つ差が生まれます。

そこで、今回の記事のポイントなのですが、汎用的に"hub browse"に渡したい文字列を整形できるようにしました。
ポイントは下記の部分です。

rev | cut -d "/" -f -2 | rev

1. rev で文字列をひっくり返す

名リトジポリ/名ザーユ/moc.buhtig/qhg./reuabatikatik/sresU/

2. cut -d "/" -f -2 で、スラッシュ区切りで先頭から2フィールド目までを取り出す

名リトジポリ/名ザーユ

3. rev で再び逆にして、ユーザ名/リポジトリ名の順番に戻す

ユーザ名/リポジトリ名


最後に作成した関数を"bindkey"コマンドで、割当がないキーにあてることで一発呼び出しができます。

bindkey '^]' peco-src
bindkey '^^' peco-src-remote



今回のzshの設定を含めたdotfilesはこちらにコミットしています。
github.com

rev は使い道に迷いますが、cut と組み合わせることで他にも面白いことができそうです。


おしまい。

Goのことはじめ その1:GOPATHとghqのルート指定

はじめに

業務でGoを触ることになったので、Goに関して気になったことをまとめていこうと思います。

GOPATH

GOPATHはGoで使う環境変数なのですが、2つの役割があります。

  1. ビルド時のインポートパスのルート(正確には$GOPATH/src配下)
  2. go getコマンドで外部パッケージをインストールしたときの、ダウンロードルートディレクト

詳細は公式ドキュメントに記載されています。
How to Write Go Code - The Go Programming Language

ghq

id:motemen さん作の、Go製のリポジトリ管理ツールです。
github.com

$ ghq get (GitHubの)ユーザ名/リポジトリ名

とすると、ローカルの "~/.ghq" というディレクトリにデフォルトでインストールされます。
"ユーザ名/リポジトリ名"の部分ですが、GitHub以外、例えばbitbucketは"https://ユーザ名@bitbucket.org/…"のように一から指定する必要があります。

Goにはgetコマンドがあるので、事足りるような気もするのですが、他にもクローンされたリポジトリを一覧したり、指定したローカルのリポジトリにcdできるので、重宝しています。

GOPATHとghqのルートをどこに設定するか

「GOPATHは適当に決めて問題ない」という記事もありましたが、個人的には適当に決めてあとで地雷を踏みたくないのが性分です。
例えば".ghq"の下にgetしたけど、やっぱりこのライブラリをインポートしたいから"go/src"の下に入れたい…となったときにシンボリックリンクを貼るのか、同じものをgo getするのかなど、色々困りそうです。

それを踏まえて、自分はこのようにしようと思います。

$GOPATH
export GOPATH=~/go
.gitconfig
[ghq]
  root = ~/.ghq
  root = ~/go/src

Go 言語のソースだけは go get で 取得し "$GOPATH/src" 以下に
そうでないものは ghq get で "~/.ghq" 以下に取得するようにしています。

  • go getした結果は "$GOPATH/src" に配置される
  • ghq getしたものも同じディレクトリに配置させるため


今回はここまでです。
次回はGoのバージョン管理システム選定について書きたいと思います。

dotfiles整理 その2:zshrcから分割した設定ファイルが読み込まれない問題への対処

kitakitabauer.hatenablog.com
前回の記事はこちら。
この構成に変えたあと、.zprofileに記述した部分が読み込まれなくなりました。

ターミナルアプリで起動されるのは、ログインシェルではなく、インタラクティブシェル

という事実を下記記事にて知りました…!
qiita.com

自分はターミナルアプリにiTerm2を使っており、下記の通りbrewインストールしたzshを起動しています。
f:id:kitakitabauer:20160913180649p:plain

前回の記事で「zshが起動時に読み込むファイルとその順番」について記述しましたが、
ログインシェルでないと、$ZDOTDIR/.zprofile は読み込まれません。

かといって、"Send text as start: "に "source $HOME/.zprofile" を入れて毎回読み込むのも、インタラクティブシェルのときに毎回読み込むことになるので、zsh標準の仕様と外れるので気持ち悪いし、セッションを起動するたびにそのコマンドが毎回出力されるのも嫌です。

ログインシェル変更

ターミナルアプリ上ではなく、ローカル設定からzshを指定するようにして対応することとします。
(なので、iTerm上の設定は"Command"→"Login shell"に変更しておきます)

まずは現在のインストールシェル一覧を確認
$ cat /etc/shells
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/bash
/bin/csh
/bin/ksh
/bin/sh
/bin/tcsh
/bin/zsh
/etc/shellsに、brewインストールされたzshのパスを追加

デフォルトインストールされたzshはバージョンが少し古いため、brewインストールしたzshのパスをroot権限で追加します。

$ sudo vi /etc/shells

…
/bin/zsh
/usr/local/bin/zsh   # 追加
ログインシェル変更

デフォルトのシェルを先ほど追加したzshに変更します。
下記コマンドによって、/etc/shellsの一番最後に記述されたzshに変更します。

$ chsh -s "$(command -v zsh)" "${USER}"
確認

読み込んだ順番を確認するために、それぞれの設定ファイルにechoを入れたあと、
ターミナルアプリの別セッションを立ち上げると、

~/.zshenv
~/.zsh/.zshenv
~/.zsh/.zprofile
~/.zsh/.zshrc

問題なし!


尚、ログインシェル変更の方法は色々あるらしいです。
rcmdnk.github.io

dotfiles整理 その1:zshの構成を見なおそう

はじめに

最近ちょっと時間ができたので、随分放置してきたdotfilesを整理をすることにしました。

まずはzsh
これまでは.zshrcに全て記述していたので、前々から役割毎に分けたいと思っていました。
大まかな方針は下記の通りです。

  1. ZDOTDIR を指定して、"~/.zsh" の下にzsh関連の設定ファイルを配置したい
  2. .zshenv、.zprofile に移譲したい

構成はこんな感じを想定しています。

/Users/kitakitabauer/.
├── .zshenv -> /Users/kitakitabauer/dotfiles/.zshenv
├── .zsh
│   ├──.zprofile -> /Users/kitakitabauer/dotfiles/.zsh/.zprofile
│   ├──.zshenv -> /Users/kitakitabauer/dotfiles/.zsh/.zshenv
│   └──.zshrc -> /Users/kitakitabauer/dotfiles/.zsh/.zshrc
└── …


環境変数 ZDOTDIR の設定

ホームディレクトリがzsh関連のファイルで埋まるのが嫌なので、ZDOTDIR を指定して、zsh関連の設定ファイルを別フォルダにて管理します。

ZDOTDIR は$HOME/.zshenv に記述します。

export ZDOTDIR=$HOME/.zsh

source $ZDOTDIR/.zshenv

これで、$HOMEに置く必要があるのは.zshenvだけになります。

zshが起動時に読み込むファイルとその順番

zshには様々な設定ファイルがあり、それらは決まった順番で読み込まれます。

ログインシェルは下記の順番で読み込まれます。

/etc/zshenv
$ZDOTDIR/.zshenv
/etc/zprofile
$ZDOTDIR/.zprofile
/etc/zshrc
$ZDOTDIR/.zshrc
/etc/zlogin
$ZDOTDIR/.zlogin

インタラクティブシェルは下記の順番で読み込まれます。

/etc/zshenv
$ZDOTDIR/.zshenv
/etc/zshrc
$ZDOTDIR/.zshrc

ログインシェルとしてzshを使うので、前述の通り.zshenv、.zprofile、.zshrcの構成でいきます。
.zloginは今のところ使用しないので作成しません。
尚、全てのユーザに影響するため、etc配下の設定ファイルは変更しません。

それぞれの設定ファイルに何を記述するか

$ZDOTDIR/.zshenv

環境変数系。ヒストリー系もここで記述します。

$ZDOTDIR/.zprofile

ログインシェルだけで使いたいaliasを記述します。

$ZDOTDIR/.zshrc

上述以外の全てを記述します。

dotfilesのシンボリックリンク生成

最後にsymlink.shにて、gitリポジトリのdotfilesに対して、$HOMEにシンボリックリンクを貼ります。

basepath=$(cd $(dirname $0);pwd)

# symlink dotfiles into ~files=.*
for file in $files
do
  if [ ! -d $file -a $file != "." -a $file != ".." -a $file != ".git" ] ; then
    ln -sf $basepath/$file ~
  fi
done

# symlink zsh configuration files into ~/.zsh
if [ ! -d ~/.zsh ] ; then
  mkdir ~/.zsh
fi
for file in .zsh/.*
do
  if [ $file != "." -a $file != ".." -a $file != ".git" ] ; then
    ln -sf $basepath/$file ~/.zsh/
  fi
done


完成

まだ工事中ですが、一旦こんな感じになりました。
github.com


次の記事はこちら
kitakitabauer.hatenablog.com

きたるISUCON6向け武者修行その4 -kataribeでHTTPリクエストのパフォーマンスを可視化しよう-

kitakitabauer.hatenablog.com

前回はNginxのチューニングを行いました。
今回はISUCONの過去問でも登場してきたプロファイリング用のツールを予習しておきます。

kataribeとは?

"Nginx/Apache/Varnishncsa Log Profiler"と書かれている通り、
アクセスログに出力されたリクエスト時間を元に、時間がかかっているアクセスをランキング化してわかりやすくしてくれるツールです。
github.com

インストール

このサイトから実行元OSのものをダウンロードします。
Releases · matsuu/kataribe · GitHub

$ wget https://github.com/matsuu/kataribe/releases/download/v0.3.0/linux_386.zip ~

unzipがなかったので、yumインストールして展開します。

$ sudo yum install unzip

$ unzip ~/linux_386.zip
Archive:  /home/vagrant/linux_386.zip
  inflating: LICENSE
  inflating: README.md
  inflating: kataribe
  inflating: kataribe.toml


ログフォーマット確認、プロファイル用ログの準備

nginx.confに定義するログフォーマットは前回設定しましたが、kataribeのREADMEに記載された通りなので問題ありません。
上記フォーマットでログを出力するために、ベンチマーカーを一度動かしておきます。

$ ./benchmarker b


アクセスログをkataribeでプロファイル

終わったら、nginxのアクセスログをkataribeに噛ませます。

$ cat /var/log/nginx/access.log | ./kataribe

Top 20 Sort By Total
Count   Total       Mean     Stddev     Min   P50.0   P90.0   P95.0   P99.0     Max   2xx  3xx  4xx  5xx  Request
  587  46.784   0.079700   0.027365   0.004   0.092   0.102   0.109   0.134   0.182     0  587    0    0  POST /login HTTP/1.1
    1  23.642  23.642000   0.000000  23.642  23.642  23.642  23.642  23.642  23.642     1    0    0    0  GET /report HTTP/1.1
 3519  14.101   0.004007   0.001516   0.001   0.004   0.006   0.007   0.009   0.013  3519    0    0    0  stylesheets
 1173   4.765   0.004062   0.001323   0.001   0.004   0.006   0.006   0.008   0.014  1173    0    0    0  images
  113   3.293   0.029142   0.012153   0.002   0.033   0.037   0.039   0.047   0.054   113    0    0    0  GET /mypage HTTP/1.1
 1060   1.645   0.001552   0.000827   0.001   0.001   0.002   0.002   0.005   0.009  1060    0    0    0  GET / HTTP/1.1

単純なリクエスト数や中央値など色々な指標で出力されますが、上記のTotalが、最も時間がかかっているリクエストパスのランキングになります。
なので、ここでは/loginを改善すればパフォーマンスが出そう!ということが考察できます。

おまけ

リクエスト時間には関係ないですが、最も多いHTTPリクエストを昇順に表示するワンライナーです。
kataribeでも"Top 20 Sort By Count"で出力されますが、ワンライナーでさくっと表示したい場合はこちらで。

$ cat /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -n
      1 /report
    113 /mypage
    587 /login
   1060 /
   1173 /images/isucon-bank.png
   1173 /stylesheets/bootflat.min.css
   1173 /stylesheets/bootstrap.min.css
   1173 /stylesheets/isucon-bank.css

Node学園 22時限目メモ

eventdots.jp
こちら、参加してきたのでメモる。

「Node学園祭 2016の告知」by yosuke furukawa さん

11/12(土)

  • dotsイベント会場で開催する予定。13日とは異なるので注意。
  • ハンズオンメイン
  • 今年もpaypalがスポンサー

11/13(日)

・James M Snell:IBMのエンジニア
・Bradley Meck:ESモジュールのCompatibleを取ってる人。ES6とNode.jsの相互運用をしている人。
・Cheng Zhao:今日本のGitHubにいる。今をときめくErectronの作者。
・Yoshua Wyuts:ChuというフロントエンドFWを作っている人。
・Mathias Buus:サンフランシスコのNode confarenceとかでよく登壇している。MongoDB Driver、Node Tetrisとか書いている。

今月中にCFP(Call For Paperpage)/sponsor pageを出します!って宣言してた。
今年もNode学園祭参加せねば!

「Stream b/w node.js & whatwg」by Jxck さん

Streamを制するものはNodeを制す から 5年
Stream APIがブラウザにやってくる!
先に結論:Node.jsのものとwhatwgのものとは互換性などない

両者の供述を聞く
In Node.js

  • 非同期はCallbackが基本
  • 引数にルールを決めて扱いやすくしよう
  • 連続するイベントはEventEmitter
  • EventEmitterの上位APIがStream
  • Multi-Consumer
  • カスタマイズは継承

In whatwg

  • 非同期はPromiseはPromiseを返してこう
  • Async/Awaitでそれを便利にしよう
  • もちろんStreamはPromiseのジェネレータ:無限にPromiseが湧いてくる
  • (≠ES6 Generator)
  • Single-Consumer:同じPromiseは得られないので
  • カスタマイズはコンストラクタ:これがなんでかはわからないらしい

あまり業務でStreamを触ることがないのでなんとも。。

IntelのEdisonで最新版のNodeを動かす」 by niccolli さん

niccolliさんはアキバの家電メーカーで電気回路の設計をしている
Intel Edison is 何?

  • 小型Linuxボード、各種無線LANBluetooth
  • Arduino互換の言語 / Node.jsで書ける
  • 組み込まれているNode.jsが古い
  • 今年6月ではv0.12、最新FWでやっとv4.4.3

組み込まれたNode.jsをアップデートしよう!
Node.jsを更新するには?
公式のLinux Binariesの32bitを落として入れれば動く。
Edisonの中身はx86Linuxで、Edision内部でビルド必要なしで、公式バイナリがそのまま動く。

USB接続で、Node.jsバージョンの切り替えを実演してた。あんなに小さいのにすごい!

「プロセスをしょうもないErrorで落とさないように頑張る」 by mookjp さん(古川さんの同僚)

要約

  • Node.jsでサーバをつくってるときに難しいと感じた点
  • 具体的にどういうことが起こったか
  • エラー処理をどう書くか

下記Qiitaを元にしたLT
qiita.com

TL;DR

プログラマが想定していなかった例外でプロセスが落ちる問題にPromiseで対処する

想定外のエラーでプロセス終了事案

  • WebSocketのクライアントとサーバがあり、サーバではイベントループ中に様々な処理をしている。
  • JSON.parseがうまくいかなかったなど想定外のエラーで巻き添えで死んでしまう。
  • 利用しているライブラリから想定外のErrorをthrowされると…
プロセスを無駄に落とさずに処理できる現実的なエラー処理
1.try-catchで書く

いわずもがな

2.非同期処理はPromiseで書くこと

同期処理時のthrowsも、非同期処理時のエラーオブジェクトも両方Promise.catch()でつかむことができる。
Promise内部でtry-catchをしてくれている。
Errorがトップレベルまで突き抜けることはなくなる。

3.unhandledRejectionイベントでログ出力

Promiseがrejectされたが、Promise.catch(func)処理がなかった場合に発火されるイベント。
Promise.catchし忘れの凡ミスでプロセスが落ちないように。
process.on('unhandledRejection', func)を書いておいてログ出力する。
最悪ログを出しておけば後で直せる。
これがないとNodeに握りつぶされるので、バグに気づかないかも・・・

4.uncaughtExceptionで終了処理させる

ログ出力してプロセスを終了させる。
uncaughtExceptionはV8レイヤでキャッチされているので、無理に継続するとイベントやプログラムの状態がおかしくなる可能性があるので復旧しないほうがいい。
yosuke furukawa さんの 「Node.js における Promise を使った例外処理」で詳しく
yosuke-furukawa.hatenablog.com

現場のコードはES6だけど、まだPromiseを使っていないので今後の参考にさせていただく!

「conventional changelog」 by kazupon さん

changelog(変更履歴)書いてますか?
書かない理由:既にVCSで変更内容とか書いてあるし…
Conventioal Changelogとは
CLIでコミットメッセージ規約ファイルを元に自動生成する
liginc.co.jp

ツール使うことで二度手間にならないなら運用する価値ありそう。

「ReactエンジニアのためのReact Native入門」 by janus_wel さん

speakerdeck.com

ほぼReactそのまま、コンパイル不要ということがでかそう!

きたるISUCON6向け武者修行その3 -Nginxのチューニングをしてみよう-

kitakitabauer.hatenablog.com
前回MySQLのチューニングを行いました。
今回はNginxのチューニングを行います。

Nginxのバージョン確認
$ nginx -v
nginx version: nginx/1.6.1

古すぎないので問題なさそうです。

デフォルトのnginx.confを確認

/etc/nginx配下のnginx.confが読み込まれるので、そちらの内容を確認します。

$ sudo vi /etc/nginx/nginx.conf
worker_processes  1;

events {
  worker_connections  1024;
}

http {
  upstream app {
    server 127.0.0.1:8080;
  }

  server {
    location / {
      proxy_pass http://app;
    }
  }
}

尚Nginxは、conf.dディレクトリに.confを作成すると起動時に読み込むので、default.confの内容も読み込まれています。
今回は /etc/nginx/nginx.conf の方をチューニングしていきます。


worker_processes変更

ワーカープロセスの数を変更します。
応答するマシン次第ですが、Nginxは複数のプロセスの要求処理を分散させることができるので、CPUが複数コアのときも対応できるように auto にします。

worker_processes auto;


keepalive追加

バックエンドサーバと保持するコネクション数を指定します。
upstreamブロックに記述します。

upstream app {
  server 127.0.0.1:8080;
  keepalive 128;
}


MIMEタイプ定義

初期で用意されているMIMEタイプ群が定義されたファイルをincludeします。
httpブロックに記述します。

include /etc/nginx/mime.types


静的ファイルのNginxキャッシュ

デフォルトだと、スタイルシートや画像ファイルに対してもアプリケーションからHTTPアクセスしているので、Nginxからリクエストしてキャッシュするように設定します。

serverブロックにcssとimagesの設定を記述しますが、
まず各locationディレクティブの上に、rootディレクティブでドキュメントルートを設定します。

root /home/isucon/webap/public;

location /stylesheets {
  open_file_cache_max=100 inactive=20s;
  expires 1d;
}

location /images {
  open_file_cache max=100 inactive=20s;
  expires 1d;
}


expiresディレクティブ

応答のキャッシュ関連ヘッダを操作します。
クライアントに送られるExpiresとCache-Controlの値を操作します。
現在から1日がファイルの有効期限として設定されます。


open_file_cacheディレクティブ

オープンファイルについての情報を格納するキャッシュを定義します。
max=X:Xはキャッシュが格納できるエントリ数で、この数に達すると、新しいエントリのためのスペースを作るために、古いエントリは削除されていきます。
inactive=Y:Yは、キャッシュエントリを格納しておく秒数です。平たくいえば、アクセスがないキャッシュの有効期限です。デフォルト60秒でキャッシュエントリをクリアします。キャッシュエントリにアクセスがあると、タイマーはリセットされます。


最終的なnginx.conf

こんな感じになりました。

worker_processes auto;

events {
    worker_connections  1024;
    # accept_mutex_delay 100ms;
    accept_mutex off;
}

http {
  upstream app {
    server 127.0.0.1:8080;
    keepalive 128;
  }

  log_format main '$remote_addr - $remote_user [$time_local] '
                   '"$request" $status $body_bytes_sent '
                   '"$http_referer" "$http_user_agent" $request_time';
  access_log /var/log/nginx/access.log main;

  include /etc/nginx/mime.types;

  server {
    listen  80;
    server_name  localhost;

    root   /home/isucon/webapp/public;

    location /stylesheets {
      open_file_cache max=100 inactive=20s;
      expires 1d;
    }

    location /images {
      open_file_cache max=100 inactive=20s;
      expires 1d;
    }

    location / {
      proxy_http_version 1.1;
      proxy_set_header Connection "";
      proxy_pass http://app;
    }
  }
}


設定ファイルの記述ルールに違反していないかチェック

設定ファイルの記述ルール上問題ないか確認します。

$ sudo /etc/init.d/nginx configtest
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful


nginx.confリロード

これまでの変更をNginxに適用します。

$ sudo service nginx reload


nginxログのパーミッション変更

admグループに所属しないユーザが見れないので、isuconユーザでも読み取り権を与えます。

$ ll -lrt /var/log/nginx/
-rw-r----- 1 nginx adm       0 Jul 14 03:14 error.log
-rw-r----- 1 nginx adm       0 Aug 19 08:42 access.log

$ sudo chmod o+r /var/log/nginx/*

$ ll -lrt /var/log/nginx/
-rw-r--r-- 1 nginx adm       0 Jul 14 03:14 error.log
-rw-r--r-- 1 nginx adm       0 Aug 19 08:42 access.log


access.log確認

ベンチマーカーを実行するかブラウザアクセスで指定したフォーマットになっているか確認します。

$ sudo tail -f /var/log/nginx/access.log
…
10.0.2.2 - - [01/Jul/2016:11:31:58 +0000] "GET / HTTP/1.1" 200 2233 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" 0.003
…
10.0.2.2 - - [01/Jul/2016:11:31:58 +0000] "GET /images/isucon-bank.png HTTP/1.1" 304 0 "http://localhost:3333/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36" 0.000


ベンチマークスコア確認

改めてベンチマーカーを実行します。

[isucon@localhost ~]$ ./benchmarker b
14:14:17 type:info	message:launch benchmarker
14:14:17 type:warning	message:Result not sent to server because API key is not set
14:14:17 type:info	message:init environment
14:14:20 type:info	message:run benchmark workload: 1
14:14:27 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:29 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:32 type:fail	reason:Expected location is miss match /, got: /mypage	method:GET	uri:/mypage
14:14:34 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:38 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:41 type:fail	reason:Expected html text is match: Wrong username or password, got This account is locked.	method:GET	uri:/
14:14:42 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:47 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:14:59 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:15:01 type:fail	reason:Response code should be 200, got 500	method:POST	uri:/login
14:15:20 type:info	message:finish benchmark workload: 1
14:15:25 type:info	message:check banned ips and locked users report
14:15:49 type:report	count:banned ips	value:2
14:15:49 type:report	count:locked users	value:2555
14:15:49 type:fail	reason:Missmatch banned Users	message:Report checking is failed. Do not send score.
14:15:49 type:score	success:5860	fail:10	score:1266

failが出るようになった…
とりあえず、Nginxのチューニングはいったんここまでとします。


次回記事はこちら