func logEndOfRequest(ctx context.Context, duration time.Duration, mw mutil.WriterProxy) { log.Ctx(ctx).WithFields(log.F{ "status": mw.Status(), "bytes": mw.BytesWritten(), "duration": duration, }).Info("Finished request") }
func printEnd(reqID string, w mutil.WriterProxy, dt time.Duration) { var buf bytes.Buffer if reqID != "" { cW(&buf, bBlack, "[%s] ", reqID) } buf.WriteString("Returning ") status := w.Status() if status < 200 { cW(&buf, bBlue, "%03d", status) } else if status < 300 { cW(&buf, bGreen, "%03d", status) } else if status < 400 { cW(&buf, bCyan, "%03d", status) } else if status < 500 { cW(&buf, bYellow, "%03d", status) } else { cW(&buf, bRed, "%03d", status) } buf.WriteString(" in ") if dt < 500*time.Millisecond { cW(&buf, nGreen, "%s", dt) } else if dt < 5*time.Second { cW(&buf, nYellow, "%s", dt) } else { cW(&buf, nRed, "%s", dt) } logs.Debug(buf.String()) }
func (l *Logger) printResponse(w mutil.WriterProxy, delta time.Duration) { var buf bytes.Buffer buf.WriteString("Returning HTTP ") status := w.Status() if status < 200 { colorWrite(&buf, bBlue, "%03d", status) } else if status < 300 { colorWrite(&buf, bGreen, "%03d", status) } else if status < 400 { colorWrite(&buf, bCyan, "%03d", status) } else if status < 500 { colorWrite(&buf, bYellow, "%03d", status) } else { colorWrite(&buf, bRed, "%03d", status) } buf.WriteString(" in ") if delta < FastResponse { colorWrite(&buf, nGreen, "%s", delta.String()) } else if delta < AcceptableResponse { colorWrite(&buf, nYellow, "%s", delta.String()) } else { colorWrite(&buf, nRed, "%s", delta.String()) } log.Print(buf.String()) }
func logEndOfRequest(ctx context.Context, duration time.Duration, mw mutil.WriterProxy) { fields := logrus.Fields{ "status": mw.Status(), "bytes": mw.BytesWritten(), "duration": duration, } log.WithFields(ctx, fields).Info("Finished request") }
// bless is the meat of kami. // It wraps a ContextHandler into an httprouter compatible request, // in order to run all the middleware and other special handlers. func bless(k ContextHandler, base *context.Context, m *middlewares, panicHandler *HandlerType, logHandler *func(context.Context, mutil.WriterProxy, *http.Request), closeHandler *func(context.Context, *http.Request)) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { ctx := defaultContext(*base, r) if len(params) > 0 { ctx = newContextWithParams(ctx, params) } ranLogHandler := false // track this in case the log handler blows up ranCloseHandler := false // track this in case the log handler blows up writer := w var proxy mutil.WriterProxy if *logHandler != nil { proxy = mutil.WrapWriter(w) writer = proxy } if *panicHandler != nil { defer func() { if err := recover(); err != nil { ctx = newContextWithException(ctx, err) wrap(*panicHandler).ServeHTTPContext(ctx, writer, r) if *closeHandler != nil && !ranCloseHandler { (*closeHandler)(ctx, r) } if *logHandler != nil && !ranLogHandler { (*logHandler)(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(http.StatusInternalServerError) } } }() } ctx, ok := m.run(ctx, writer, r) if ok { k.ServeHTTPContext(ctx, writer, r) } if *closeHandler != nil { ranCloseHandler = true (*closeHandler)(ctx, r) } if *logHandler != nil { ranLogHandler = true (*logHandler)(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(http.StatusInternalServerError) } } }
// bless is the meat of kami. // It wraps a HandleFn into an httprouter compatible request, // in order to run all the middleware and other special handlers. func bless(k ContextHandler) httprouter.Handle { return func(w http.ResponseWriter, r *http.Request, params httprouter.Params) { ctx := Context if len(params) > 0 { ctx = newContextWithParams(Context, params) } ranLogHandler := false // track this in case the log handler blows up writer := w var proxy mutil.WriterProxy if LogHandler != nil { proxy = mutil.WrapWriter(w) writer = proxy } if PanicHandler != nil { defer func() { if err := recover(); err != nil { ctx = newContextWithException(ctx, err) wrap(PanicHandler).ServeHTTPContext(ctx, writer, r) if LogHandler != nil && !ranLogHandler { LogHandler(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(500) } } }() } ctx, ok := run(ctx, writer, r) if ok { k.ServeHTTPContext(ctx, writer, r) } if LogHandler != nil { ranLogHandler = true LogHandler(ctx, proxy, r) // should only happen if header hasn't been written proxy.WriteHeader(500) } } }