コマンドラインを複数回実行して実行時間を計測するツールを書いた
なんか最近ツール系のやつを趣味で高速化したりしていて、PR投げるときに速くなったよと説明するときに手元で何度か計測して、平均値とか調べるのがめんどいなと思って、複数回実行して平均/標準偏差を表示してくれるツールを作った。
もっと定番のがあるような気がするけど、あんまり聞いたことがない。
Usage of benchcmd: -n int number of times to run (default 10) -summary only output summary result
$ benchcmd -n 10 'go version' run "go version" 15.711435ms 19.42685ms 19.967876ms 24.896109ms 19.557516ms 21.698995ms 16.499163ms 22.28795ms 23.461732ms 18.743192ms count: 10 times executed avg: 20.225081ms stdev: 2.634089ms
importするだけですべてのHTTP通信をログる
今回のisuconに対応できなかったので、作ろうと思ったけど、id:motemenさんが既に作ってた
昔見た記憶があったのだけど、すっかり記憶から忘れていた。
何msぐらいかかったかとかは出てこないので出力できるようにしてみたが、拡張方法が互換性がないのでmergeしてもらえないかもしれない。
とりあえずmergeされなくても使えるように整えておいた。
isuconで惨敗しました
isuconでチームフリー素材として参加しました。54,868点で8位でした
今回は、開発環境の構築で色々とてこずりました。
DBがpostgresqlだったので、手元で構築しようとしていたときに、brew updateしてしまい、postgresqlのdatabaseのバージョンが一致しないので起動できないという状態になってしまいました。それで色々やっていると、手元のdatabaseを壊してしまってちょっと復旧は諦め、3台のうち1台を開発サーバーにしました。
deployできるようにしようとしていたのですが、手元からsshはとおるのですが、サーバー間でsshがつながらない状態だったので、iptablesなどを疑ったのですが、わからず、仕方なく、手元へbinaryをscpして、remoteへscpしなおすshell scriptを書いてなんとかしました。 sshがつながらなかったのは、懇親会で聞いたところ、hosts.denyの設定がされていたから、だったらしいです。
ようやく色々できるようになったのが、13:30ごろでだいぶ出遅れてしまいました。
serviceを取得する処理がN+1クエリだったので、INを使うように書き換えました。(追加がないのはその時点でわかっていたので、他のチームのようにハードコーディングするべきだった)
あとは他の人へ指示を出しつつ、curlでどのAPIがどのぐらいキャッシュできそうか、などを確認していました。
tenkiは最後まで悩んでいたのですが、curlを連打していると同じ結果が返ってくるので数秒ならいけそうと試してみたらtestが通ったので、徐々にあげてみて、2秒で落ちつきました。
グローバルIPしか持っていなかったので、どうやって複数台で分散させようか悩んだのですが、前回のようにログイン後のRedirect時に別のIPへRedirectさせたらどうか、ということでやってみましたが、test部分でfailしていたので、諦めてnginxでグローバルIPを直でproxyするのを試したりしました。
ただ、DB部分をグローバルIPでアクセスさせるという発想はなかったので、結局諦めて1台でがんばることにしました。
色々知識不足などで効率的に動けなかったので、復習して次回に備えようと思います。
2行書きかえるだけでSQLをログに出力できるようになるgo-sql-tracerを作りました
isucon予選中に、SQLを出力したくなったのだけど、ふとgithub.com/shogo82148/go-sql-proxyを使ってみようとしてとりあえず簡単に使う方法が書いてなくて少し使い方を調べるのに苦労したので、isuconで時間のロスなく使えるようにそのwrapperを書きました。
package main import ( database/sql "github.com/go-sql-driver/mysql" # load driver before load go-sql-tracer _ "github.com/walf443/go-sql-tracer" ) func main() { db, err := sql.Open('mysql:trace', dsn) }
ポイントは、
です。
今database/sqlに登録されているドライバ一覧から、go-sql-tracerのinit内で、':trace'をつけてドライバを登録しているので使いたいドライバの後でimportする必要があります。
go-sql-proxyはカスタマイズも柔軟にでき、非常に素晴らしいライブラリですが、カスタマイズしなくてもいいのでとりあえずSQLのログみたい、というときは非常に便利かと思います。
じわじわチャットへ通知する
なんかのバッチを実行していて、それが出力するログをじわじわチャットへ通知したい。(そのバッチはそれなりに時間がかかるものとする)
何も考慮しなければ、たとえばslackであれば、
# #!/bin/bash # notify_chat.sh exec tee >(while read line; do curl -s --data '$line' $SLACK_ENDPOINT -o/dev/null; done
みたいにやれば、
$ ruby batch.rb | notify_chat.sh
で毎行slackさんへ通知してくれる。
このやり方だと、場所によってはAPIをどばっと叩いてしまって負荷をかけてしまったりするので、1秒間の出力はまとめてわたせるようにするコマンドthrottleというものを書いてみた。
$ ruby batch.rb | tee >(throttle -interval 1s "curl -s --data '%%DATA%%' $SLACK_ENDPOINT -o /dev/null")
みたいにやると、1秒間の出力はまとめてcurlコマンドへ渡してくれる。1秒間の出力は、%%DATA%%の部分が置きかえられて実行される
$ go install github.com/walf443/throttle
でインストールできる
ソースは、
Chrome拡張でCocoaPodsのPodfile.lockのdiffからも各ライブラリの変更へ飛べるようになった
昨日だしたやつが、CocoaPodsのPodfile.lockのdiffからもclickできるようになりました。
また、Pull Requestのページのdiffで発動しなかった問題を修正しました。
権限まわりを変更している関係で、既にインストールした人はv0.0.2にアップグレードされた人は、無効になっていることがあるので注意してください。
Github Library Changes - Chrome ウェブストア
関連
githubのGemfile.lockやpackage.jsonのdiffからそれぞれのライブラリのdiffへ飛べるChrome拡張を作った
ChangeLogのファイルはプロジェクトにあったりなかったりなので、githubのリポジトリのタグ間のdiffへクリックでいけるようにしてみた。
これでbundle updateとかしたときにざっくりどういう更新があったのか確認ができる。
現在は、Gemfile.lockのdiffと、package.jsonのdiffに対応している。
Github Library Changes - Chrome ウェブストア