-
-
Save cespare/3985516 to your computer and use it in GitHub Desktop.
| type ApacheLogRecord struct { | |
| http.ResponseWriter | |
| ip string | |
| time time.Time | |
| method, uri, protocol string | |
| status int | |
| responseBytes int64 | |
| elapsedTime time.Duration | |
| } | |
| func (r *ApacheLogRecord) Log(out io.Writer) { | |
| timeFormatted := r.time.Format("02/Jan/2006 03:04:05") | |
| requestLine := fmt.Sprintf("%s %s %s", r.method, r.uri, r.protocol) | |
| fmt.Fprintf(out, ApacheFormatPattern, r.ip, timeFormatted, requestLine, r.status, r.responseBytes, | |
| r.elapsedTime.Seconds()) | |
| } | |
| func (r *ApacheLogRecord) Write(p []byte) (int, error) { | |
| written, err := r.ResponseWriter.Write(p) | |
| r.responseBytes += int64(written) | |
| return written, err | |
| } | |
| func (r *ApacheLogRecord) WriteHeader(status int) { | |
| r.status = status | |
| r.ResponseWriter.WriteHeader(status) | |
| } | |
| type ApacheLoggingHandler struct { | |
| handler http.Handler | |
| out io.Writer | |
| } | |
| func NewApacheLoggingHandler(handler http.Handler, out io.Writer) http.Handler { | |
| return &ApacheLoggingHandler{ | |
| handler: handler, | |
| out: out, | |
| } | |
| } | |
| func (h *ApacheLoggingHandler) ServeHTTP(rw http.ResponseWriter, r *http.Request) { | |
| clientIP := r.RemoteAddr | |
| if colon := strings.LastIndex(clientIP, ":"); colon != -1 { | |
| clientIP = clientIP[:colon] | |
| } | |
| record := &ApacheLogRecord{ | |
| ResponseWriter: rw, | |
| ip: clientIP, | |
| time: time.Time{}, | |
| method: r.Method, | |
| uri: r.RequestURI, | |
| protocol: r.Proto, | |
| status: http.StatusOK, | |
| elapsedTime: time.Duration(0), | |
| } | |
| startTime := time.Now() | |
| h.handler.ServeHTTP(record, r) | |
| finishTime := time.Now() | |
| record.time = finishTime.UTC() | |
| record.elapsedTime = finishTime.Sub(startTime) | |
| record.Log(h.out) | |
| } |
| func main() { | |
| mux := http.DefaultServeMux | |
| mux.HandleFunc("/", indexHandler) | |
| loggingHandler := NewApacheLoggingHandler(mux, os.Stderr) | |
| server := &http.Server{ | |
| Addr: fmt.Sprintf(":%s", 2345), | |
| Handler: loggingHandler, | |
| } | |
| server.ListenAndServe() | |
| } |
ApacheFormatPattern is not defined in this code. Could you clarify?
edit: I found it in another of your repos: const apacheFormatPattern = "%s - - [%s] "%s %s %s" %d %d %.4f\n"
edit edit: If anyone is interested in seeing this in the gorilla mux framework, i've used the above idea over at https://github.com/jadekler/git-go-websiteskeleton
This seems to be the proper ApacheFormatPattern for this code
const (
ApacheFormatPattern = "%s - - [%s] \"%s %d %d\" %f\n"
)
Hey. This implementation's AWESOME! What's the license for this code snippet in case I want to derive and use it in my code? Some form of CC? MIT? BSD? WTFPL?
Also curious about the license. I've copied a derivative[1], modified slightly to suit my needs and added a Negroni middleware to the package. I want to share that package, but depends on the license.
Great code!