func httpLog() martini.Handler { return func(w http.ResponseWriter, r *http.Request, ctx martini.Context, rid httphelper.RequestId) { timer := time.Now() // start time of request ctx.Next() // execute the other handler rw := w.(martini.ResponseWriter) loginfo := fmt.Sprintf("[Access] [#%s] [status:%v] [ip:%s] [host:%s] [method:%s] [path:%s] [user-agent:%s] [ref:%s] [time:%.3fms]", string(rid), // request id rw.Status(), // http status code httphelper.GetIP(r), // client IP r.Host, r.Method, r.URL, r.Header["User-Agent"][0], r.Referer(), time.Since(timer).Seconds()*1000) // request time (milliseconds) global.Logger.Info(loginfo) } }
func (this *RanServer) accessLog(sniffer *hhelper.ResponseSniffer, r *http.Request, responseTime int64) error { buf := bufferPool.Get() defer bufferPool.Put(buf) var in bool // TODO read layout from config for _, c := range LogLayoutNormal { if in { switch c { case '%': buf.WriteString("%") // request id case 'i': buf.WriteString(sniffer.Header().Get("X-Request-Id")) // response status code case 's': buf.WriteString(strconv.Itoa(sniffer.Code)) // host case 'h': buf.WriteString(r.Host) // client ip address case 'a': buf.WriteString(hhelper.GetIP(r)) // request method case 'm': buf.WriteString(r.Method) // request url case 'l': buf.WriteString(r.URL.String()) // referer case 'r': buf.WriteString(r.Referer()) // user agent case 'u': buf.WriteString(r.Header.Get("User-Agent")) // number of bytes transferred case 'n': buf.WriteString(strconv.Itoa(sniffer.Size)) // response time case 't': rt := float64(responseTime) / 1000000 buf.WriteString(fmt.Sprintf("%.3fms", rt)) // compression status (gzip / none) case 'c': contentEncoding := strings.ToLower(sniffer.Header().Get("Content-Encoding")) if strings.Contains(contentEncoding, "gzip") { buf.WriteString("gzip") } else { buf.WriteString("none") } default: return ErrInvalidLogLayout } in = false } else { if c == '%' { in = true } else { buf.WriteRune(c) } } } this.logger.Info(buf.String()) return nil }