func buildsShowHandler(c web.C, w http.ResponseWriter, r *http.Request) {
	if db == nil {
		fmt.Fprintf(w, "database logging not enabled")
		return
	}

	id := fmt.Sprintf("%s/%s", c.URLParams["name"], c.URLParams["repo_tag"])
	var build Build
	if err := build.Get(id); err != nil {
		w.Header().Set("Content-Type", "text/plain")
		switch err {
		case sql.ErrNoRows:
			log.Printf("[%s] build with id='%s' doesn't exist", middleware.GetReqID(c), id, err)
			http.Error(w, fmt.Sprintf("404 build %s not found", id), 404)
		default:
			log.Printf("[%s] error fetching build with id='%s': %v", middleware.GetReqID(c), id, err)
			http.Error(w, err.Error(), 500)
		}
		return
	} else {
		w.Header().Set("Content-Type", "text/html")
		fmt.Fprintf(w,
			"<p>&larr; %s</p><h3>%s</h3><p>revision: %s<br>created: %s<br>completed: %s<br>success: %v %s<br>output:</p><pre>%s</pre>",
			linkTo("/", "all builds"),
			build.Id,
			githubRevisionLink(&build),
			build.CreatedAt,
			build.CompletedAt,
			build.Success,
			builderImgForBuild(&build),
			build.Output)
	}
}
Пример #2
0
// Middleware that recovers from panics, sends email if a notification email
// has been provided, and log issues.
func recoverHandler(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		reqID := middleware.GetReqID(*c)

		defer func() {
			if err := recover(); err != nil {
				buf := make([]byte, 1<<16)
				size := runtime.Stack(buf, false)
				stackTrace := string(buf[0:size])
				message := fmt.Sprintf("Panic detected on request %s:\n%+v\nIP: %v, URL: %s\nStack trace:\n%s\n",
					reqID, err, r.RemoteAddr, r.URL.Path, stackTrace)
				dvid.Criticalf("%s\n", message)

				if err := SendNotification(message, nil); err != nil {
					dvid.Criticalf("Couldn't send email notifcation: %v\n", err)
				}

				http.Error(w, http.StatusText(500), 500)
			}
		}()

		h.ServeHTTP(w, r)
	}
	return http.HandlerFunc(fn)
}
func (rec recoverer) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	reqID := gmiddleware.GetReqID(*rec.c)

	defer func() {
		if r := recover(); r != nil {
			var err error
			switch x := r.(type) {
			case error:
				err = x
			default:
				err = fmt.Errorf("%v", x)
			}
			rec.l.WithFields(logrus.Fields{
				"req_id": reqID,
				"method": req.Method,
				"uri":    req.RequestURI,
				"remote": req.RemoteAddr,
				"err":    err.Error(),
				"stack":  stack.Callers(0),
			}).Warn("service.err")
			http.Error(resp, http.StatusText(500), 500)
		}
	}()

	rec.h.ServeHTTP(resp, req)

}
Пример #4
0
func recoverer(c *web.C, h http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		id := middleware.GetReqID(*c)

		// Raven recoverer
		defer func() {
			var packet *raven.Packet
			switch rval := recover().(type) {
			case nil:
				return
			case error:
				packet = raven.NewPacket(rval.Error(), raven.NewHttp(r), raven.NewException(rval, raven.NewStacktrace(2, 3, nil)))
			default:
				str := fmt.Sprintf("%+v", rval)
				packet = raven.NewPacket(str, raven.NewHttp(r), raven.NewException(errors.New(str), raven.NewStacktrace(2, 3, nil)))
			}

			debug.PrintStack()
			http.Error(w, http.StatusText(500), 500)

			env.Raven.Capture(packet, map[string]string{
				"request_id": id,
			})
		}()

		h.ServeHTTP(w, r)
	})
}
Пример #5
0
func (ac *ActiveContext) InfoLog(msg string) {
	rID := middleware.GetReqID(ac.Context)
	ac.Logger.InfoWithFields(msg, map[string]interface{}{
		"req_id": rID,
		"uri":    ac.Request.RequestURI,
	})
}
Пример #6
0
// Logger returns a Goji web middleware that logs web transactions in the format
// I want.
func Logger(c *web.C, h http.Handler) http.Handler {

	fn := func(w http.ResponseWriter, r *http.Request) {
		startTime := time.Now()
		fields := log.Fields{
			"requestId": middleware.GetReqID(*c),
			"client":    r.RemoteAddr,
			"url":       r.URL.String(),
			"method":    r.Method,
			"protocol":  r.Proto,
			"referer":   r.Referer(),
			"start":     startTime,
		}
		log.WithFields(fields).Debug("Request started.")
		lw := mutil.WrapWriter(w)
		h.ServeHTTP(lw, r)
		endTime := time.Now()
		duration := endTime.Sub(startTime)
		fields["duration"] = duration.Nanoseconds()
		status := lw.Status()
		fields["status"] = status
		switch {
		case status < 300: // 100- and 200-series statuses
			log.WithFields(fields).Info("OK")
		case status < 400: // 300-series redirection
			log.WithFields(fields).Info("Redirected")
		case status < 500: // 400-series client error
			log.WithFields(fields).Warn("Client error")
		default: // 500-series server erorr
			log.WithFields(fields).Error("Server error!")
		}
	}
	return http.HandlerFunc(fn)
}
Пример #7
0
func (glogr glogrus) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
	start := time.Now()
	reqID := middleware.GetReqID(*glogr.c)
	glogr.l.WithFields(logrus.Fields{
		"req_id": reqID,
		"uri":    req.RequestURI,
		"method": req.Method,
		"remote": req.RemoteAddr,
	}).Info("New request incoming")
	lresp := wrapWriter(resp)

	glogr.h.ServeHTTP(lresp, req)
	lresp.maybeWriteHeader()

	latency := float64(time.Since(start)) / float64(time.Millisecond)

	glogr.l.WithFields(logrus.Fields{
		"req_id":  reqID,
		"status":  lresp.status(),
		"method":  req.Method,
		"uri":     req.RequestURI,
		"remote":  req.RemoteAddr,
		"latency": fmt.Sprintf("%6.4f ms", latency),
		"app":     glogr.name,
	}).Info("Finished serving the request")
}
Пример #8
0
func (ac *ActiveContext) ParamsLog(params interface{}) {
	rid := middleware.GetReqID(ac.Context)
	uri := ac.Request.RequestURI
	ac.Logger.ParamsWithFields(params, map[string]interface{}{
		"datetime": time.Now().Format("2006-01-02 15:04:05"),
		"req_id":   rid,
		"uri":      uri,
	})
}
//Route is used because our handlers returns *app.Err
func (b *BaseHandler) Route(h AppH) func(web.C, http.ResponseWriter, *http.Request) {
	fn := func(c web.C, w http.ResponseWriter, r *http.Request) {
		err := h(c, w, r)
		if err != nil {
			reqID := gmiddleware.GetReqID(c)
			b.Logr.WithFields(logrus.Fields{
				"req_id": reqID,
				"err":    err.Error(),
			}).Error("response.err")

			http.Error(w, http.StatusText(err.HTTPStatus), err.HTTPStatus)
		}
	}
	return fn
}
func buildsIndexHandler(c web.C, w http.ResponseWriter, r *http.Request) {
	if db == nil {
		fmt.Fprintf(w, "database logging not enabled")
		return
	}

	builds := []Build{}
	err := db.Select(&builds, "SELECT * FROM builds ORDER BY created_at DESC")
	if err != nil {
		log.Printf("[%s] error listing builds: %v", middleware.GetReqID(c), err)
		http.Error(w, err.Error(), 500)
		return
	}
	w.Header().Set("Content-Type", "text/html")
	fmt.Fprintf(w, "all builds: <br>")
	for _, build := range builds {
		fmt.Fprintf(w, "%s <a href='/%s'>%s</a> created at %s <br>", builderImgForBuild(&build), build.Id, build.Id, build.CreatedAt)
	}
}
// RequestIDHeader adds a Request-Id in response header.
func RequestIDHeader(c *web.C, h http.Handler) http.Handler {
	fn := func(resp http.ResponseWriter, req *http.Request) {
		var requestID string
		given := req.Header.Get("X-Request-Id")
		if given != "" {
			requestID = given
		}
		given = req.Header.Get("Request-Id")
		if given != "" {
			requestID = given
		}
		if requestID == "" && c.Env["requestID"] != "" {
			requestID = gmiddleware.GetReqID(*c)
		}
		resp.Header().Set("Request-Id", requestID)
		h.ServeHTTP(resp, req)
	}
	return http.HandlerFunc(fn)
}
Пример #12
0
func (ac *ActiveContext) ErrorLog(e error) {
	rID := middleware.GetReqID(ac.Context)
	if ac.Env == EnvDevelopment {
		stack := make([]byte, 4096)
		read := runtime.Stack(stack, false)
		ac.Logger.ErrorWithFields(e, map[string]interface{}{
			"datetime":   time.Now().Format("2006-01-02 15:04:05"),
			"req_id":     rID,
			"uri":        ac.Request.RequestURI,
			"stacktrace": string(stack[:read]),
		})
	} else {
		ac.Logger.ErrorWithFields(e, map[string]interface{}{
			"datetime": time.Now().Format("2006-01-02 15:04:05"),
			"req_id":   rID,
			"uri":      ac.Request.RequestURI,
		})
	}
}
Пример #13
0
// LoggerMiddleware is the middleware that logs http requests and resposnes
// to the logging subsytem of horizon.
func LoggerMiddleware(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		ctx := gctx.FromC(*c)
		mw := mutil.WrapWriter(w)

		logger := log.WithField("req", middleware.GetReqID(*c))

		ctx = log.Set(ctx, logger)
		gctx.Set(c, ctx)

		logStartOfRequest(ctx, r)

		then := time.Now()
		h.ServeHTTP(mw, r)
		duration := time.Now().Sub(then)

		logEndOfRequest(ctx, duration, mw)
	}

	return http.HandlerFunc(fn)
}
Пример #14
0
// ContextFromC returns a new context bound with the value of the request id in
// the provide goji context
func ContextFromC(ctx context.Context, c *web.C) context.Context {
	reqid := middleware.GetReqID(*c)
	return Context(ctx, reqid)
}
Пример #15
0
func logForReq(c web.C, message string) {
	log.Printf("[%s] %s", middleware.GetReqID(c), message)
}
Пример #16
0
// instanceSelector retrieves the data instance given its complete string name and
// forwards the request to that instance's HTTP handler.
func instanceSelector(c *web.C, h http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		if httpUnavailable(w) {
			return
		}

		var err error
		dataname := dvid.InstanceName(c.URLParams["dataname"])
		uuid, ok := c.Env["uuid"].(dvid.UUID)
		if !ok {
			msg := fmt.Sprintf("Bad format for UUID %q\n", c.Env["uuid"])
			BadRequest(w, r, msg)
			return
		}
		data, err := datastore.GetDataByUUIDName(uuid, dataname)
		if err != nil {
			BadRequest(w, r, err)
			return
		}
		v, err := datastore.VersionFromUUID(uuid)
		if err != nil {
			BadRequest(w, r, err)
			return
		}

		if data.Versioned() {
			// Make sure we aren't trying mutable methods on committed nodes.
			locked, err := datastore.LockedUUID(uuid)
			if err != nil {
				BadRequest(w, r, err)
				return
			}
			if locked && data.IsMutationRequest(r.Method, c.URLParams["keyword"]) {
				BadRequest(w, r, "Cannot do %s on endpoint %q of locked node %s", r.Method, c.URLParams["keyword"], uuid)
				return
			}
		} else {
			// Map everything to root version.
			v, err = datastore.GetRepoRootVersion(v)
			if err != nil {
				BadRequest(w, r, err)
				return
			}
		}
		ctx := datastore.NewVersionedCtx(data, v)

		// Also set the web request information in case logging needs it downstream.
		ctx.SetRequestID(middleware.GetReqID(*c))

		// Handle DVID-wide query string commands like non-interactive call designations
		queryStrings := r.URL.Query()

		// All HTTP requests are interactive so let server tally request.
		interactive := queryStrings.Get("interactive")
		if interactive == "" || (interactive != "false" && interactive != "0") {
			GotInteractiveRequest()
		}

		// TODO: setup routing for data instances as well.
		if config != nil && config.AllowTiming() {
			w.Header().Set("Timing-Allow-Origin", "*")
		}
		data.ServeHTTP(uuid, ctx, w, r)
	}
	return http.HandlerFunc(fn)
}