2017年2月27日月曜日

go-swagger でリクエスト情報をロギングしてみた

概要

どんな Web アプリでもリクエストされた情報はロギングしたいと思います
今回は go-swagger でリクエスト情報をロギングしてみたいと思います
ロギングする情報はリクエストメソッド、パス、ボディになります
使用するアプリケーションはこれまでに作成した TODO アプリを使用します

環境

  • CentOS 6.7 64bit
  • go-swagger dev
  • golang 1.6
  • swagger ui v2.2.10

ソース修正

  • cd $GOPATH/src/github.com/hawksnowlog/todo-list
  • vim restapi/configure_todo_list.go

import の追加

import (
        "bytes"
        "io/ioutil"
        "log"
)

既存の import に追記してください

ロギング用ハンドラメソッドの追加

func addLogging(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
                buf, _ := ioutil.ReadAll(r.Body)
                rdr1 := ioutil.NopCloser(bytes.NewBuffer(buf))
                rdr2 := ioutil.NopCloser(bytes.NewBuffer(buf))
                r.Body = rdr2
                bufbody := new(bytes.Buffer)
                bufbody.ReadFrom(rdr1)
                body := bufbody.String()
                log.Println("received request:", r.Method, r.URL, body)
                next.ServeHTTP(w, r)
        })
}

ここでポイントですが、r.Body の情報を 2 つのバッファに分割しています
これは r.Body をそのまま ReadFrom にかけてしまうと r.Body の情報が失われてしまい、この後の go-swagger 側の処理で body がないと言われエラーになってしまうからです
なので、一度分割して使っていない方を再度 r.Body に設定しています

ロギング処理のコール

func setupGlobalMiddleware(handler http.Handler) http.Handler {
        handleCORS := cors.Default().Handler
        return handleCORS(addLogging(handler))
}

swagger ui に対応するために CORS の処理を入れたので更にその処理にロギング処理を追加します
こんな感じで go-swagger はハンドラを何個も挟むことで、別の処理を追加することができます

動作確認

  • cd $GOPATH/src/github.com/hawksnowlog/todo-list
  • go fmt restapi/configure_todo_list.go
  • go install ./cmd/todo-list-server/
  • todo-list-server --host=0.0.0.0 --port=18080

でアプリを起動して

  • curl -XPOST -H "Content-Type: application/io.goswagger.examples.todo-list.v1+json" "http://127.0.0.1:18080/v1/" -d '{"description":"test2", "completed":true}'

でアクセスすると

2017/02/23 14:57:10 received request: POST /v1/ {"description":"test2", "completed":true}

こんな感じのログが出力されると思います
ログファイルに出力したい場合はコード内でファイルに出力するようにしても良いですし todo-list-server --host=0.0.0.0 --port=18080 >> log 2>&1 こんな感じで出力をリダイレクトしても良いと思います

参考サイト

0 件のコメント:

コメントを投稿