Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Goの net/http のClientにHAR形式でログ取れるTransportを作ってみた #42

Merged
merged 4 commits into from Oct 3, 2019

Conversation

@vvakame
Copy link
Owner

commented Oct 1, 2019

sinmetalと話をして、GCSとかCloud Pub/Subは裏がREST APIなので、Transportで頑張ればプロダクションコードに手を加えずにモック実装にできるのでは?という会話があった。
そっちはそっちでやるといいと思うんだけど、裏側で行われている通信内容をとりあえずチェックしたくない?という気持ちになったのでやってみることにした。

HTTPリクエストの可視化というとまぁ HARファイルじゃない?ということで net/http のClientのTransport(RoundTripper)にログ取りの処理を突っ込んでみるべ、という発想で作られたのがこのライブラリ。

https://github.com/vvakame/go-harlog

vvakame added a commit to vvakame/go-harlog that referenced this pull request Oct 1, 2019
@vvakame

This comment has been minimized.

Copy link
Owner Author

commented Oct 1, 2019

とりあえず適当にGCSにアクセスしてHARファイルを作ってみる。
こんな感じの使い方です。
Transportを https://github.com/vvakame/go-harlog 製のものに置き換えて後は普通に実行する。
処理が終わったらJSONにしてどこかに出力しておく。

ctx := context.Background()

hc, err := google.DefaultClient(ctx, storage.ScopeReadWrite)
if err != nil {
	panic(err)
}

// inject HAR logger!
har := &harlog.Transport{
	Transport: hc.Transport,
}
hc.Transport = har

client, err := storage.NewClient(
	ctx,
	option.WithHTTPClient(hc),
)
if err != nil {
	panic(err)
}

bucket := client.Bucket(*bucket)

{
	object := bucket.Object("2019-10-01-harlog/hello.txt")
	r, err := object.NewReader(ctx)
	if err != nil {
		panic(err)
	}
	b, err := ioutil.ReadAll(r)
	if err != nil {
		panic(err)
	}
	fmt.Println(string(b))
}
{
	object := bucket.Object("2019-10-01-harlog/goodnight.txt")
	w := object.NewWriter(ctx)
	_, err = w.Write([]byte("Good night, world!"))
	if err != nil {
		panic(err)
	}
	err = w.Close()
	if err != nil {
		panic(err)
	}
}

// dump HAR file!
b, err := json.MarshalIndent(har.HAR(), "", "  ")
if err != nil {
	panic(err)
}
err = ioutil.WriteFile("gcs.har", b, 0644)
if err != nil {
	panic(err)
}

HARファイルのインポート

ChromeのDevToolsとかで見れる。
連続して同じファイルをimportしようとすると黙って無視したりされて若干不親切なので、こっち使ったほうがいいかもしれない。

@vvakame

This comment has been minimized.

Copy link
Owner Author

commented Oct 1, 2019

GCSからファイルを読み出す処理のログの様子。
ヘッダ類、レスポンス、各種タイミングが記録されているのがわかる。

Headers

Response

Timing

@vvakame

This comment has been minimized.

Copy link
Owner Author

commented Oct 1, 2019

2回目のファイルの書き込みの様子。
Timingを見ると、DNS Lookup, Initial connection, SSL にグラフが出ている。
2回目のアクセスだからここはゼロになるのが正しいのでは…?と思ったが、よく見るとドメインが異なった。
APIによってアクセスするドメインが異なるのか… 知らなかった…。

Headers

Preview

Timing

みたいなことがわかる。

@vvakame

This comment has been minimized.

Copy link
Owner Author

commented Oct 1, 2019

gRPCでも同様のことができるといいなーと思うけど、streamとかあるしHAR形式では難しいかな…。
REST APIとかでは便利だけどgRPCとかでは無力…!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.