예제 #1
0
// ServeHTTPContext implements the httpx.Handler interface. It recovers from
// panics and returns an error for upstream middleware to handle.
func (h *Recovery) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) (err error) {
	ctx = reporter.WithReporter(ctx, h.Reporter)

	// Add the request to the context.
	reporter.AddRequest(ctx, r)

	// Add the request id
	reporter.AddContext(ctx, "request_id", httpx.RequestID(ctx))

	defer func() {
		if v := recover(); v != nil {
			err = fmt.Errorf("%v", v)

			if v, ok := v.(error); ok {
				err = v
			}

			reporter.Report(ctx, err)

			return
		}
	}()

	err = h.handler.ServeHTTPContext(ctx, w, r)

	return
}
예제 #2
0
파일: middleware.go 프로젝트: brianz/empire
// PrefixRequestID adds the request as a prefix to the log15.Logger.
func PrefixRequestID(h httpx.Handler) httpx.Handler {
	return httpx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		if l, ok := logger.FromContext(ctx); ok {
			if l, ok := l.(log15.Logger); ok {
				ctx = logger.WithLogger(ctx, l.New("request_id", httpx.RequestID(ctx)))
			}
		}

		return h.ServeHTTPContext(ctx, w, r)
	})
}
예제 #3
0
func (h *Logger) ServeHTTPContext(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	l := logger.New(log.New(h.Device, fmt.Sprintf("request_id=%s ", httpx.RequestID(ctx)), 0))
	ctx = logger.WithLogger(ctx, l)

	l.Log(
		"at", "request",
		"method", r.Method,
		"path", fmt.Sprintf(`"%s"`, r.URL.Path),
	)

	return h.handler.ServeHTTPContext(ctx, w, r)
}
예제 #4
0
파일: request.go 프로젝트: brianz/empire
// WithRequest adds information about the http.Request to reported errors.
func WithRequest(h httpx.Handler) httpx.Handler {
	return httpx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		ctx = httpx.WithRequest(ctx, r)

		// Add the request to the context.
		reporter.AddRequest(ctx, r)

		// Add the request id
		reporter.AddContext(ctx, "request_id", httpx.RequestID(ctx))

		return h.ServeHTTPContext(ctx, w, r)
	})
}
예제 #5
0
// Common wraps the httpx.Handler with some common middleware.
func Common(h httpx.Handler, opts CommonOpts) http.Handler {
	l := &log{opts.Logger}

	// Recover from panics.
	h = middleware.Recover(h, opts.Reporter)

	// Add a logger to the context.
	h = middleware.LogTo(h, func(ctx context.Context, r *http.Request) logger.Logger {
		return l.New("request_id", httpx.RequestID(ctx))
	})

	// Wrap the route in middleware to add a context.Context.
	return middleware.BackgroundContext(h)
}
예제 #6
0
func TestRequestID(t *testing.T) {
	m := &RequestID{
		handler: httpx.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
			requestID := httpx.RequestID(ctx)

			if got, want := requestID, "1234"; got != want {
				t.Fatalf("RequestID => %s; want %s", got, want)
			}

			return nil
		}),
	}

	ctx := context.Background()
	resp := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/", nil)
	req.Header.Set("X-Request-ID", "1234")

	if err := m.ServeHTTPContext(ctx, resp, req); err != nil {
		t.Fatal(err)
	}
}
예제 #7
0
파일: logger.go 프로젝트: frewsxcv/empire
func stdLogger(out io.Writer) func(context.Context, *http.Request) logger.Logger {
	return func(ctx context.Context, r *http.Request) logger.Logger {
		return logger.New(log.New(out, fmt.Sprintf("request_id=%s ", httpx.RequestID(ctx)), 0))
	}
}