GoのWebアプリケーションのSQLロガーとパフォーマンス分析ツールを作ってみた
はじめに
この記事は Go2 Advent Calendar 2018の記事です。
担当の10日より1時間ほど投稿が遅れてしまったことをお詫びします。
今回は、拙作のGo製のWebアプリケーションにSQLのクエリロガーを仕込めるOSS『graqt』 を紹介したいと思います。
過去に書いた記事を足して2で割ったような記事なので、graqtを知ってる方は読まなくてもいいと思います。*1
graqtとは
go-request-and-query-loggerです。
発音はガラクタでお願いします。
Go用のアクセスログとクエリのログを記録するためのhttp handlerミドルウェアで、そのログを解析するためのツールもついてます。
使い方
シンプルなWebアプリケーションの実装例
package main import ( "database/sql" "fmt" "math/rand" "net/http" "os" "time" _ "github.com/go-sql-driver/mysql" // 2つパッケージを追加してください "github.com/justinas/alice" "github.com/serinuntius/graqt" ) var ( // 2つ変数を追加してください traceEnabled = os.Getenv("GRAQT_TRACE") driverName = "mysql" db *sql.DB ) func init() { rand.Seed(time.Now().UnixNano()) } func main() { // ifを追加して 環境変数 GRAQT_TRACEが1のときだけログを吐きます。 // ISUCONで本番ベンチのときは オフにしておいたほうがいいと思います。 // しかし、パフォーマンスには結構気を使ったので、そんなに低下はしないと思います。 if traceEnabled == "1" { // driverNameは絶対にこれでお願いします。 driverName = "mysql-tracer" // もし、ログを吐く場所を変えたかったら以下のメソッドを呼んで下さい。 // デフォルトは、 query.logとrequest.logが このGoファイル(main.go)と同じディレクトリに出ると思います。 // graqt.SetQueryLogger("log/query.log") // graqt.SetRequestLogger("log/request.log") } var err error // ここを先程の変数に変更してください db, err = sql.Open(driverName, "root:@/graqt") if err != nil { panic(err) } defer db.Close() mux := http.NewServeMux() mux.HandleFunc("/user", createUser) // ミドルウェアを追加します。 var chain alice.Chain if traceEnabled == "1" { chain = alice.New(graqt.RequestId) } else { chain = alice.New() } // ミドルウェアを渡します http.ListenAndServe(":8080", chain.Then(mux)) } func createUser(w http.ResponseWriter, r *http.Request) { // contextを使用する方のメソッドに変えてください。 ctx := r.Context() stmt, _ := db.PrepareContext(ctx, "INSERT INTO `user` (email,age) VALUES (?, ?)") t1 := time.Now().UnixNano() age := rand.Intn(80) stmt.ExecContext(ctx, fmt.Sprintf("hoge%d@hoge.com", t1), age) w.Write([]byte(`ok`)) }
CLI部分
gocuiというパッケージを使って実装しています。
graqt夜の部の進捗。
— あおいちゃん⛓️ハッカソンマスター (@_serinuntius) August 17, 2018
今日はGIFにしてみた。
query windowを表示したり、閉じたりできるようになった!
リファクタして各windowごとのファイルにわけた。https://t.co/6JZQyklKlP#golang #isucon #graqt pic.twitter.com/xkkubqmeBi
今はこれより進化してて、普通に全部の情報が正しく表示されるはずです。
まとめ
ある程度便利なの作ったはずなので、煮るなり焼くなりしてあげてください。