詩と創作・思索のひろば

ドキドキギュンギュンダイアリーです!!!

Fork me on GitHub

ソースに一行追加するだけですべての HTTP 通信をロギングするモジュールを書いた #golang

こちらです。Perl でいうと Devel::KYTProf に性質がちかい。

motemen/go-loghttp · GitHub (GoDoc)

使用例

たとえばこういうコードに…

package main

import (
    "io"
    "log"
    "net/http"
    "os"
)

func main() {
    resp, err := http.Get(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    io.Copy(os.Stdout, resp.Body)
}
% go run main.go http://example.com/
<!doctype html>
...

一行追加すると:

package main

import (
    "io"
    "log"
    "net/http"
    "os"

    _ "github.com/motemen/go-loghttp/global" // ← この行
)

func main() {
    resp, err := http.Get(os.Args[1])
    if err != nil {
        log.Fatal(err)
    }

    io.Copy(os.Stdout, resp.Body)
}
% go run main.go http://example.com/
2014/12/02 13:36:27 ---> GET http://example.com/
2014/12/02 13:36:27 <--- 200 http://example.com/
<!doctype html>
...

こんな風に(log パッケージを使った)ログが自動的に吐かれるようになります。

特定のクライアントだけログを吐きたいのなら:

import "github.com/motemen/go-loghttp"

...

client := http.Client{
        Transport: &loghttp.Transport{},
}

loghttp.Transport の LogRequset、LogResponse フィールドを設定することで、どのようにログを出力するかをカスタマイズできます。(デフォルトでは上記のように標準の log パッケージを使用してます)

仕組み

loghttp は loghttp.Transport という struct を提供していて、これが http.RoundTripper を実装しているので http.Client の Transport フィールドとして設定できます。http.Cilent が HTTP リクエストを実行する際にはこの Transport を介して行いますが、loghttp.Transport は通常の HTTP 送受信に加えてロギングを行うような実装になっているので、このように HTTP 通信に引っかけてリクエストとレスポンスのロギングを行うことができるわけです。

さらに github.com/motemen/go-loghttp/global パッケージでは http.DefaultTransportloghttp.DefaultTransport に書き換え(!)しているので、インポートするだけですべての HTTP 通信が(標準の http パッケージを利用していれば)標準エラー出力に表示されるようになります。

The Way to Go: A Thorough Introduction to the Go Programming Language (English Edition)

The Way to Go: A Thorough Introduction to the Go Programming Language (English Edition)

はてなで一緒に働きませんか?