From 76538f515ea4439be5bb0069dff32832f06ce127 Mon Sep 17 00:00:00 2001 From: codeskyblue Date: Thu, 28 Jul 2016 17:17:05 +0800 Subject: [PATCH] update dep --- Godeps/Godeps.json | 4 + .../github.com/mash/go-accesslog/.gitignore | 1 + .../mash/go-accesslog/README.markdown | 49 ++++++ .../github.com/mash/go-accesslog/accesslog.go | 147 ++++++++++++++++++ 4 files changed, 201 insertions(+) create mode 100644 vendor/github.com/mash/go-accesslog/.gitignore create mode 100644 vendor/github.com/mash/go-accesslog/README.markdown create mode 100644 vendor/github.com/mash/go-accesslog/accesslog.go diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 64c17f7..60a2fc9 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -46,6 +46,10 @@ "ImportPath": "github.com/gorilla/mux", "Comment": "v1.1-15-gd391bea", "Rev": "d391bea3118c9fc17a88d62c9189bb791255e0ef" + }, + { + "ImportPath": "github.com/mash/go-accesslog", + "Rev": "9ba8e13f36087d6cb83d9a9f17f9e8da137d5ee9" } ] } diff --git a/vendor/github.com/mash/go-accesslog/.gitignore b/vendor/github.com/mash/go-accesslog/.gitignore new file mode 100644 index 0000000..9ed3b07 --- /dev/null +++ b/vendor/github.com/mash/go-accesslog/.gitignore @@ -0,0 +1 @@ +*.test diff --git a/vendor/github.com/mash/go-accesslog/README.markdown b/vendor/github.com/mash/go-accesslog/README.markdown new file mode 100644 index 0000000..7cf4a6f --- /dev/null +++ b/vendor/github.com/mash/go-accesslog/README.markdown @@ -0,0 +1,49 @@ +Custom format HTTP access logger in golang +========================================== + +## Description + +A library to build your own HTTP access logger. + +## Usage + +Provide a class that implements `accesslog.Logger` interface to make a logging HTTP handler. + +``` golang +type LogRecord struct { + Time time.Time + Ip, Method, Uri, Protocol, Username string + Status int + Size int64 + ElapsedTime time.Duration + CustomRecords map[string]string +} + +type Logger interface { + Log(record LogRecord) +} +``` + +## Example + +``` golang +import ( + "log" + "net/http" + + accesslog "github.com/mash/go-accesslog" +) + +type logger struct { +} + +func (l logger) Log(record accesslog.LogRecord) { + log.Println(record.Method + " " + record.Uri) +} + +func main() { + l := logger{} + handler := http.FileServer(http.Dir(".")) + http.ListenAndServe(":8080", accesslog.NewLoggingHandler(handler, l)) +} +``` diff --git a/vendor/github.com/mash/go-accesslog/accesslog.go b/vendor/github.com/mash/go-accesslog/accesslog.go new file mode 100644 index 0000000..79285c4 --- /dev/null +++ b/vendor/github.com/mash/go-accesslog/accesslog.go @@ -0,0 +1,147 @@ +package accesslog + +import ( + "bufio" + "fmt" + "net" + "net/http" + "strings" + "time" +) + +type LogRecord struct { + Time time.Time + Ip, Method, Uri, Protocol, Username, Host string + Status int + Size int64 + ElapsedTime time.Duration + RequestHeader http.Header + CustomRecords map[string]string +} + +type LoggingWriter struct { + http.ResponseWriter + logRecord LogRecord +} + +func (r *LoggingWriter) Write(p []byte) (int, error) { + if r.logRecord.Status == 0 { + // The status will be StatusOK if WriteHeader has not been called yet + r.logRecord.Status = http.StatusOK + } + written, err := r.ResponseWriter.Write(p) + r.logRecord.Size += int64(written) + return written, err +} + +func (r *LoggingWriter) WriteHeader(status int) { + r.logRecord.Status = status + r.ResponseWriter.WriteHeader(status) +} + +// w.(accesslogger.LoggingWriter).SetCustomLogRecord("X-User-Id", "3") +func (r *LoggingWriter) SetCustomLogRecord(key, value string) { + if r.logRecord.CustomRecords == nil { + r.logRecord.CustomRecords = map[string]string{} + } + r.logRecord.CustomRecords[key] = value +} + +func (r *LoggingWriter) CloseNotify() <-chan bool { + return r.ResponseWriter.(http.CloseNotifier).CloseNotify() +} + +func (r *LoggingWriter) Hijack() (net.Conn, *bufio.ReadWriter, error) { + if hijacker, ok := r.ResponseWriter.(http.Hijacker); ok { + return hijacker.Hijack() + } + return nil, nil, fmt.Errorf("ResponseWriter doesn't support Hijacker interface") +} + +type Logger interface { + Log(record LogRecord) +} + +type LoggingHandler struct { + handler http.Handler + logger Logger + logBefore bool +} + +func NewLoggingHandler(handler http.Handler, logger Logger) http.Handler { + return &LoggingHandler{ + handler: handler, + logger: logger, + logBefore: false, + } +} + +func NewAroundLoggingHandler(handler http.Handler, logger Logger) http.Handler { + return &LoggingHandler{ + handler: handler, + logger: logger, + logBefore: true, + } +} + +func NewLoggingMiddleware(logger Logger) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + handler := NewLoggingHandler(next, logger) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler.ServeHTTP(w, r) + }) + } +} + +func NewAroundLoggingMiddleware(logger Logger) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + handler := NewAroundLoggingHandler(next, logger) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + handler.ServeHTTP(w, r) + }) + } +} + +func (h *LoggingHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + ip := strings.Split(r.RemoteAddr, ":")[0] + + username := "-" + if r.URL.User != nil { + if name := r.URL.User.Username(); name != "" { + username = name + } + } + + startTime := time.Now() + writer := &LoggingWriter{ + ResponseWriter: rw, + logRecord: LogRecord{ + Time: startTime.UTC(), + Ip: ip, + Method: r.Method, + Uri: r.RequestURI, + Username: username, + Protocol: r.Proto, + Host: r.Host, + Status: 0, + Size: 0, + ElapsedTime: time.Duration(0), + RequestHeader: r.Header, + }, + } + + if h.logBefore { + writer.SetCustomLogRecord("at", "before") + h.logger.Log(writer.logRecord) + } + h.handler.ServeHTTP(writer, r) + finishTime := time.Now() + + writer.logRecord.Time = finishTime.UTC() + writer.logRecord.ElapsedTime = finishTime.Sub(startTime) + + if h.logBefore { + writer.SetCustomLogRecord("at", "after") + } + h.logger.Log(writer.logRecord) +}